knitr::opts_chunk$set(echo = TRUE, collapse = TRUE, 
                      tidy = TRUE, message = FALSE, 
                      warning = FALSE)
library(flowCore)
library(flowTime)
library(ggplot2)
library(stringr)                        
library(ggridges)
library(dplyr)
library(tidyr)
library(tidyverse)
library(drc)
library(gridExtra)
library(openCyto)
library(ggcyto)
library(flowStats)
library(flowClust)
library(wesanderson)
library(patchwork)
library(ggthemes)
library(agricolae)

Time-course response and ratiometric measurement of the single-fusion biosensors

Time-course degradation

# Read in flow sets from 20200611 and 20200614
flowSet <- read.plateSet(path = "~/Google Drive/Shared drives/PlantSynBioLab/Data/Mahbub/FlowSets/", pattern = "202006", phenoData = "annotation.txt")
flowSet <- flowSet[which(flowSet@phenoData@data$strain %in% c("T1T1", "A2A2"))]

write.flowSet(flowSet, "flowSets/single-time-course")
flowSet <- read.flowSet(path =  "flowSets/single-time-course", phenoData = "annotation.txt")
# load gates for this strain/cytometer
load("PSB_Accuri_W303.RData")
data_sum <- summarizeFlow(flowset = flowSet, ploidy = "diploid", only = "singlets")
[1] "Gating with diploid singlet gates..."
time0_14 <- data_sum %>% dplyr::filter(name == "21D10.fcs") %>% 
  pull(btime) 
time0_11 <- data_sum %>% dplyr::filter(name == "11G02.fcs") %>% 
  pull(btime) 
data_sum <- 
  data_sum %>% 
    mutate(time = case_when(
      folder == "20200611_AFB_epistasis" ~ 
        .$btime - time0_11, 
      folder == "20200614_AFB_epistasis" ~
        .$btime - time0_14
    ))
shapes <- c("DMSO" = 1, "IAA" = 16)
lines <- c("DMSO" = 2, "IAA" = 1)

data_sum$ratio <- data_sum$FL1.Amean/data_sum$FL4.Amean
data_sum$Venus <- data_sum$FL1.Amean/10000
data_sum_long <- data_sum %>% 
  dplyr::select(time, treatment, yWL, folder, strain, ratio, Venus) %>%
  pivot_longer(cols = c(ratio, Venus), names_to = "parameter")
deg_plot <- ggplot(data = subset(data_sum_long, yWL == "166"), 
       aes(x = time, y = value, shape = treatment, 
           color = treatment, 
           group = interaction(treatment, folder))) + 
  geom_point() + labs(y = "intensity (AU)", x = "time post auxin addition (min)") +
  facet_wrap(~fct_rev(parameter), scales = "free") + 
  scale_shape_manual(values = shapes) + 
  geom_line(aes(linetype = treatment)) +
  scale_linetype_manual(values = lines) + 
  scale_color_viridis_d(option = "D", end = 0.75, direction = -1) + 
  theme_test()
deg_plot

data <- flowTime::tidyFlow(flowSet, ploidy = "diploid", only = "singlets")
[1] "No further gating applied."
[1] "Converting events..."
# get late time points for one strain
last_reading <- 
  tail(unique(data[which(data$yWL == 166), "name"]),4) %>% head(2)
data <- dplyr::filter(data, yWL == "166" & name %in% last_reading)
# clean this up, cut off zeros
data <- subset(data, FL1.A >1 & FL4.A > 1)
data$FLratio <- data$FL1.A/data$FL4.A
range(data$FL1.A)
[1]     21 697262
#calculate cvs
sd(data$FLratio)/mean(data$FLratio)
[1] 0.1842678
range(data$FLratio)
[1] 0.002628614 3.836085188

Single-fusion CV plot

#calculate normalized values
data$Venus <- data$FL1.A / median(data$FL1.A)
data$mScarlet <- data$FL4.A / median(data$FL4.A)
data$ratio <- data$FLratio / median(data$FLratio)
# make a tidy, long dataset 
data_long <- data %>% 
  dplyr::select(treatment, Venus, mScarlet, ratio) %>%
  pivot_longer(cols = c(Venus, mScarlet, ratio), 
               names_to = "parameter", 
               values_to = "value") 

# need to also format CVs approriately for annotating
cv <- function(x) return(round(sd(x)/mean(x),2))
CVs <- data %>% group_by(treatment) %>%
  summarise(across(where(is_double), cv))
CVs <- CVs %>% dplyr::select(treatment, Venus, mScarlet, ratio) %>%
    pivot_longer(cols = c(Venus, mScarlet, ratio), 
               names_to = "parameter", 
               values_to = "value")

CV_plot <- ggplot(data = data_long, 
       mapping = aes(x = value, 
                     color = treatment)) + 
  geom_density() + coord_cartesian(x = c(0,2)) + 
  labs(x = "median normalized intensity", color = "treatment") + 
  facet_grid(fct_relevel(parameter, "Venus")~.) + theme_test() + 
  geom_text(data = subset(CVs, treatment == "IAA"), 
             aes(label = paste0("CV = ", value)),
             x = 0.3, y = 2) + 
  geom_text(data = subset(CVs, treatment == "DMSO"), 
             aes(label = paste0("CV = ", value)), 
            x = 1.8, y = 2) + 
  scale_color_viridis_d(option = "D", end = .75, direction = -1)
CV_plot

layout <- "
AAAAB
CCCCC
"
CV_plot  + guide_area() + deg_plot + plot_annotation(tag_levels = "A") + 
  plot_layout(guides = "collect", heights = c(5, 2), design = layout) 
ggsave("ratio-deg.pdf", width = 5, height = 5)
ggsave("ratio-deg.png", width = 5, height = 5)

Dose-response curves of dual-fusion AFB2 and TIR1 biosensors

AFB2-based biosensor (yWL210 AFB2 dual-fusion, single ratiometric construct)

plate_all_210 <- read.plateSet(path = "~/Google Drive/Shared drives/PlantSynBioLab/Pat/Experiments/Does-response assay/11212022_DRA_overlaydata/Combine Data_yWL210/All data/", pattern = "DRA-*") 

annotation <- createAnnotation(yourFlowSet = plate_all_210)
write.csv(annotation,'/Users/patchaisupa/Google Drive/Shared drives/PlantSynBioLab/Pat/Experiments/Does-response assay/11212022_DRA_overlaydata/overlaydata_annotation_yWL210_datagated_exJan31.csv')
annotation <-
  read.csv(
    '~/Google Drive/Shared drives/PlantSynBioLab/Pat/Experiments/Does-response assay/11212022_DRA_overlaydata/overlaydata_annotation_yWL210_datagated_exJan31.csv'
  )

aplate_all_210 <-
  annotateFlowSet(yourFlowSet = plate_all_210,
                  annotation_df = annotation,
                  mergeBy = 'name')
head(rownames(pData(aplate_all_210)))
head(pData(aplate_all_210))
write.flowSet(aplate_all_210, 
              outdir = "flowSets/AFB2-dual-yWL210-dose-response")
aplate_all_210 <-
  read.flowSet(path = "flowSets/AFB2-dual-yWL210-dose-response", 
               phenoData = "annotation.txt")

plate_all_210_sum <-
  summarizeFlow(aplate_all_210, channel = NA, gated = TRUE)
[1] "Summarizing all events..."

###Dose-response curve

Comparing log-logistic and Weibull models

(Figure 2 in Ritz (2009))

fitdrc.m1 <-
  drm(YL1.Amean / BL1.Amean ~ dose, data = plate_all_210_sum, fct = LL.4())
fitdrc.m2 <-
 drm(YL1.Amean / BL1.Amean ~ dose, data = plate_all_210_sum, fct = W1.4())
#fitdrc.m3 <- 
# drm(YL1.Amean/BL1.Amean~dose, data=plate_all_210_sum, fct = W2.4())
#Error in drmOpt(opfct, opdfct1, startVecSc, optMethod, constrained, warnVal, :
#Convergence failed

summary(fitdrc.m1)

Model fitted: Log-logistic (ED50 as parameter) (4 parms)

Parameter estimates:

                Estimate Std. Error t-value p-value    
b:(Intercept) -1.5032417  0.6338695 -2.3715 0.01985 *  
c:(Intercept)  0.0526074  0.0020790 25.3043 < 2e-16 ***
d:(Intercept)  0.0845079  0.0021128 39.9976 < 2e-16 ***
e:(Intercept)  0.0403739  0.0159429  2.5324 0.01306 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error:

 0.01246335 (90 degrees of freedom)
summary(fitdrc.m2)

Model fitted: Weibull (type 1) (4 parms)

Parameter estimates:

                Estimate Std. Error t-value   p-value    
b:(Intercept) -0.7846961  0.2493021 -3.1476  0.002233 ** 
c:(Intercept)  0.0522487  0.0021769 24.0009 < 2.2e-16 ***
d:(Intercept)  0.0847793  0.0022414 37.8241 < 2.2e-16 ***
e:(Intercept)  0.0189778  0.0111048  1.7090  0.090902 .  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error:

 0.01263587 (90 degrees of freedom)
#summary(fitdrc.m3)

The 4-parameter log-logistic model has a slightly lower residual standard error.

model.LL4_all_210 <-
  drm(YL1.Amean / BL1.Amean ~ dose,
      data = plate_all_210_sum,
      fct = LL.4(names = c(
        "Slope", "Lower Limit", "Upper Limit", "ED50"
      )))
plot(
  model.LL4_all_210,
  broken = TRUE,
  type = "none",
  lty = 1,
  lwd = 5,
  xlab = "Extracellular IAA concentration (µM)",
  ylab = "Response Signal"
)
#plot(model.LL4_all_210, broken = TRUE, col = "black", add=TRUE)
plot(
  model.LL4_all_210,
  broken = TRUE,
  type = "confidence",
  col = "black",
  add = TRUE
)

summary(model.LL4_all_210)

Model fitted: Log-logistic (ED50 as parameter) (4 parms)

Parameter estimates:

                          Estimate Std. Error t-value p-value    
Slope:(Intercept)       -1.5032417  0.6338695 -2.3715 0.01985 *  
Lower Limit:(Intercept)  0.0526074  0.0020790 25.3043 < 2e-16 ***
Upper Limit:(Intercept)  0.0845079  0.0021128 39.9976 < 2e-16 ***
ED50:(Intercept)         0.0403739  0.0159429  2.5324 0.01306 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error:

 0.01246335 (90 degrees of freedom)

Individual replicate dose-response curves

replicate1_210 <-
  drm(
    YL1.Amean / BL1.Amean ~ dose,
    data = subset(plate_all_210_sum, replicate == "1"),
    fct = LL.4()
  )
replicate2_210 <-
  drm(
    YL1.Amean / BL1.Amean ~ dose,
    data = subset(plate_all_210_sum, replicate == "2"),
    fct = LL.4()
  )
replicate3_210 <-
  drm(
    YL1.Amean / BL1.Amean ~ dose,
    data = subset(plate_all_210_sum, replicate == "3"),
    fct = LL.4()
  )
replicate4_210 <-
  drm(
    YL1.Amean / BL1.Amean ~ dose,
    data = subset(plate_all_210_sum, replicate == "4"),
    fct = LL.4()
  )
replicate5_210 <-
  drm(
    YL1.Amean / BL1.Amean ~ dose,
    data = subset(plate_all_210_sum, replicate == "5"),
    fct = LL.4()
  )
replicate6_210 <-
  drm(
    YL1.Amean / BL1.Amean ~ dose,
    data = subset(plate_all_210_sum, replicate == "6"),
    fct = LL.4()
  )
replicate7_210 <-
  drm(
    YL1.Amean / BL1.Amean ~ dose,
    data = subset(plate_all_210_sum, replicate == "7"),
    fct = LL.4()
  )

plot(
  replicate1_210,
  broken = TRUE,
  type = "all",
  col = "dark green",
  lty = 2
)
plot(
  replicate2_210,
  broken = TRUE,
  add = TRUE,
  type = "all",
  col = "dark blue",
  lty = 2
)
plot(
  replicate3_210,
  broken = TRUE,
  add = TRUE,
  type = "all",
  col = "yellow",
  lty = 2
)
plot(
  replicate4_210,
  broken = TRUE,
  add = TRUE,
  type = "all",
  col = "dark grey",
  lty = 2
)
plot(
  replicate5_210,
  broken = TRUE,
  add = TRUE,
  type = "all",
  col = "dark orange",
  lty = 2
)
plot(
  replicate6_210,
  broken = TRUE,
  add = TRUE,
  type = "all",
  col = "brown",
  lty = 2
)
plot(
  replicate7_210,
  broken = TRUE,
  add = TRUE,
  type = "all",
  col = "dark red",
  lty = 2
)
plot(
  model.LL4_all_210,
  broken = TRUE,
  add = TRUE,
  type = "none",
  lty = 1,
  lwd = 5,
  xlab = "Extracellular IAA concentration (µM)",
  ylab = "Response Signal"
)
#plot(model.LL4_all_210, broken = TRUE, col = "black", add=TRUE)
plot(
  model.LL4_all_210,
  broken = TRUE,
  type = "confidence",
  col = "black",
  add = TRUE
)

TIR1-based biosensor (yWL209 TIR dual-fusion, single ratiometric construct)

plate_all_209 <-
  read.plateSet(path = "~/Google Drive/Shared drives/PlantSynBioLab/Pat/Experiments/Does-response assay/11212022_DRA_overlaydata/Combine Data_yWL209/", pattern = "DRA-*") 
annotation <- createAnnotation(yourFlowSet = plate_all_209)
write.csv(
  annotation,
  '/Users/patchaisupa/Google Drive/Shared drives/PlantSynBioLab/Pat/Experiments/Does-response assay/11212022_DRA_overlaydata/overlaydata_annotation_yWL209.csv'
)
annotation <-
  read.csv(
    '~/Google Drive/Shared drives/PlantSynBioLab/Pat/Experiments/Does-response assay/11212022_DRA_overlaydata/overlaydata_annotation_yWL209.csv'
  )

aplate_all_209 <-
  annotateFlowSet(yourFlowSet = plate_all_209,
                  annotation_df = annotation,
                  mergeBy = 'name')
head(rownames(pData(aplate_all_209)))
head(pData(aplate_all_209))

write.flowSet(aplate_all_209, outdir = "flowSets/TIR1-dual-yWL209-dose-response")
aplate_all_209 <-
  read.flowSet(path = "flowSets/TIR1-dual-yWL209-dose-response", 
               phenoData = "annotation.txt")

dat_sum_overlaydata_209 <-
  summarizeFlow(aplate_all_209, gated = TRUE)
[1] "Summarizing all events..."

###Dose-response curve

model.LL4_rep1_209 <-
  drm(
    YL1.Amean / BL1.Amean ~ dose,
    data = subset(dat_sum_overlaydata_209, replicate == "1"),
    fct = LL.4(names = c(
      "Slope", "Lower Limit", "Upper Limit", "ED50"
    ))
  )
plot(
  model.LL4_rep1_209,
  type = "all",
  col = "red",
  lty = 1,
  lwd = 2,
  xlab = "Extracellular IAA concentration (µM)",
  ylab = "Red/Green Fluorescent Ratio"
)
plot(
  model.LL4_rep1_209,
  broken = TRUE,
  type = "confidence",
  col = "red",
  add = TRUE
)

print(summary(model.LL4_rep1_209))

Model fitted: Log-logistic (ED50 as parameter) (4 parms)

Parameter estimates:

                          Estimate Std. Error t-value   p-value    
Slope:(Intercept)       -0.3671010  0.1395354 -2.6309   0.03901 *  
Lower Limit:(Intercept)  0.0960915  0.0019149 50.1808 4.201e-09 ***
Upper Limit:(Intercept)  0.1200258  0.0068403 17.5470 2.198e-06 ***
ED50:(Intercept)         1.4438822  2.8035445  0.5150   0.62496    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error:

 0.002705295 (6 degrees of freedom)
model.LL4_rep2_209 <-
  drm(
    YL1.Amean / BL1.Amean ~ dose,
    data = subset(dat_sum_overlaydata_209, replicate == "2"),
    fct = LL.4(names = c(
      "Slope", "Lower Limit", "Upper Limit", "ED50"
    ))
  )
plot(
  model.LL4_rep2_209,
  type = "all",
  col = "blue",
  lty = 1,
  lwd = 2,
  xlab = "Extracellular IAA concentration (µM)",
  ylab = "Red/Green Fluorescent Ratio"
)
plot(
  model.LL4_rep2_209,
  broken = TRUE,
  type = "confidence",
  col = "blue",
  add = TRUE
)

print(summary(model.LL4_rep2_209))

Model fitted: Log-logistic (ED50 as parameter) (4 parms)

Parameter estimates:

                          Estimate Std. Error t-value   p-value    
Slope:(Intercept)       -0.4323121  0.1153679 -3.7472  0.005646 ** 
Lower Limit:(Intercept)  0.0998826  0.0018914 52.8084 1.833e-11 ***
Upper Limit:(Intercept)  0.1372100  0.0062312 22.0197 1.910e-08 ***
ED50:(Intercept)         1.4546642  1.4213107  1.0235  0.336036    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error:

 0.003755989 (8 degrees of freedom)
model.LL4_rep3_209 <-
  drm(
    YL1.Amean / BL1.Amean ~ dose,
    data = subset(dat_sum_overlaydata_209, replicate == "3"),
    fct = LL.4(names = c(
      "Slope", "Lower Limit", "Upper Limit", "ED50"
    ))
  )
plot(
  model.LL4_rep3_209,
  type = "all",
  col = "dark green",
  lty = 1,
  lwd = 2,
  xlab = "Extracellular IAA concentration (µM)",
  ylab = "Red/Green Fluorescent Ratio"
)
plot(
  model.LL4_rep3_209,
  broken = TRUE,
  type = "confidence",
  col = "dark green",
  add = TRUE
)


print(summary(model.LL4_rep3_209))

Model fitted: Log-logistic (ED50 as parameter) (4 parms)

Parameter estimates:

                          Estimate Std. Error t-value   p-value    
Slope:(Intercept)       -0.4007190  0.2177393 -1.8404    0.1030    
Lower Limit:(Intercept)  0.0984103  0.0018186 54.1128 1.509e-11 ***
Upper Limit:(Intercept)  0.1148849  0.0037802 30.3916 1.492e-09 ***
ED50:(Intercept)         0.9199369  1.1883595  0.7741    0.4611    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error:

 0.002908608 (8 degrees of freedom)
model.LL4_all_209 <-
  drm(YL1.Amean / BL1.Amean ~ dose,
      data = dat_sum_overlaydata_209,
      fct = LL.4(names = c(
        "Slope", "Lower Limit", "Upper Limit", "ED50"
      )))
plot(
  model.LL4_all_209,
  type = "all",
  col = "black",
  lty = 1,
  lwd = 3
)
plot(
  model.LL4_all_209,
  broken = TRUE,
  col = "black",
  add = TRUE
)
plot(
  model.LL4_all_209,
  broken = TRUE,
  type = "confidence",
  col = "black",
  add = TRUE
)
print(summary(model.LL4_all_209))

Model fitted: Log-logistic (ED50 as parameter) (4 parms)

Parameter estimates:

                          Estimate Std. Error t-value   p-value    
Slope:(Intercept)       -0.3420811  0.0895742 -3.8190 0.0004353 ***
Lower Limit:(Intercept)  0.0973731  0.0014017 69.4690 < 2.2e-16 ***
Upper Limit:(Intercept)  0.1337956  0.0109331 12.2377 1.972e-15 ***
ED50:(Intercept)        10.9140480 20.3972838  0.5351 0.5954208    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error:

 0.004904408 (42 degrees of freedom)
replicate1_209 <-
  drm(
    YL1.Amean / BL1.Amean ~ dose,
    data = subset(dat_sum_overlaydata_209, replicate == "1"),
    fct = LL.4()
  )
replicate2_209 <-
  drm(
    YL1.Amean / BL1.Amean ~ dose,
    data = subset(dat_sum_overlaydata_209, replicate == "2"),
    fct = LL.4()
  )
replicate3_209 <-
  drm(
    YL1.Amean / BL1.Amean ~ dose,
    data = subset(dat_sum_overlaydata_209, replicate == "3"),
    fct = LL.4()
  )


plot(
  replicate1_209,
  broken = TRUE,
  add = TRUE,
  type = "none",
  col = "red",
  lty = 2
)
plot(
  replicate2_209,
  broken = TRUE,
  add = TRUE,
  type = "none",
  col = "blue",
  lty = 2
)
plot(
  replicate3_209,
  broken = TRUE,
  add = TRUE,
  type = "none",
  col = "dark green",
  lty = 2
)

Combined Dose-response curveswith ggplot

pm210 <-
  expand.grid(treatment = exp(seq(log(1e-5), log(1e2), length = 1000)))
pm210 <-
  cbind(pm210,
        predict(model.LL4_all_210, newdata = pm210, interval = "confidence"))  

plot210 <-
  ggplot(plate_all_210_sum, aes(x = dose, y = YL1.Amean / BL1.Amean))  + 
  scale_x_log10() + geom_ribbon(
    data = pm210,
    aes(
      x = treatment,
      y = Prediction,
      ymin = Lower,
      ymax = Upper
    ),
    alpha = 0.4
  ) + geom_line(data = pm210,
                aes(x = treatment, y = Prediction),
                linewidth = 1.2) + ylab("mScarlet-I/Venus") + xlab("Auxin (IAA, µM)") + 
  scale_x_log10(labels = 
                  scales::label_number(drop0trailing = TRUE)) +  
  scale_color_viridis_c() +
  geom_point(aes(color = replicate), size = 1, alpha = 0.6) + 
  theme_classic() + 
  theme(legend.position = "none", 
        plot.title = element_text(hjust = 0.5),
        plot.title.position = "plot") + 
  ggtitle("AFB2")  
plot210



pm209 <-
  expand.grid(treatment = exp(seq(log(1e-5), log(1e2), length = 1000)))
pm209 <-
  cbind(pm209,
        predict(model.LL4_all_209, newdata = pm209, interval = "confidence"))

plot209 <-
  ggplot(dat_sum_overlaydata_209, aes(x = dose, y = YL1.Amean / BL1.Amean))  + 
  scale_x_log10() + geom_ribbon(
    data = pm209,
    aes(
      x = treatment,
      y = Prediction,
      ymin = Lower,
      ymax = Upper
    ),
    alpha = 0.4
  ) + geom_line(data = pm209,
                aes(x = treatment, y = Prediction),
                linewidth = 1.2) + 
  ylab("mScarlet-I/Venus") + 
  xlab("Auxin (IAA, µM)") + 
  scale_x_log10(labels = 
                  scales::label_number(drop0trailing = TRUE)) + 
  scale_color_viridis_c() +
  geom_point(aes(color = replicate), size = 1, alpha = 0.6) +
  theme_classic() + 
  theme(legend.position = "none", 
        plot.title = element_text(hjust = 0.5),
        plot.title.position = "plot") + 
  #ylim(0.095, 0.12) + 
  ggtitle("TIR1")
plot209


plot210 + plot209 + patchwork::plot_annotation(tag_levels = "A")

ggsave(
  plot = plot210 + plot209 + patchwork::plot_annotation(tag_levels = "A"),
  filename = "dose-response.pdf",
  width = 6,
  height = 3
)
ggsave(
  plot = plot210 + plot209 + patchwork::plot_annotation(tag_levels = "A"),
  filename = "dose-response.png",
  width = 6,
  height = 3
)

LCMS measurements of intracellular auxin

plate_08052022 <- read.plateSet(path = "~/Google Drive/Shared drives/PlantSynBioLab/Pat/Experiments/Does-response assay/08052022_yWL210_DRA-LCMS-R2/Alldata/", pattern = "DRA*") 
annotation <- read.csv('~/Google Drive/Shared drives/PlantSynBioLab/Pat/Experiments/Does-response assay/08052022_yWL210_DRA-LCMS-R2/08052022_alldata_annotation.csv')

aplate_08052022 <- annotateFlowSet(yourFlowSet = plate_08052022, annotation_df = annotation, mergeBy = 'name')
head(rownames(pData(aplate_08052022)))
head(pData(aplate_08052022))
write.flowSet(aplate_08052022, "flowSets/AFB2-dual-DR-LCMS")
summary(model.LL4_08052022_LCMS)

Model fitted: Log-logistic (ED50 as parameter) (4 parms)

Parameter estimates:

                           Estimate  Std. Error t-value   p-value    
Slope:(Intercept)       -5.6514e-01  8.9868e-02 -6.2885 4.016e-05 ***
Lower Limit:(Intercept)  3.7324e-02  3.6766e-01  0.1015    0.9208    
Upper Limit:(Intercept)  2.6037e+02  2.7474e+02  0.9477    0.3620    
ED50:(Intercept)         1.1866e+05  2.1885e+05  0.5422    0.5976    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error:

 1.019652 (12 degrees of freedom)

Auxin-induced degradation time-course assay for the dual-fusion biosensors in different yeast strains

Two isolated colonies from each strain were selected at random and tested in auxin-induced protein degradation assay. IAA working solution was added to obtain the IAA concentration at 50 µM in each culture. The assay was carried out using ThermoFisher Attune NxT B/Y flow cytometer.

Strains:

plate_03112022 <- read.plateSet(path = "~/Google Drive/Shared drives/PlantSynBioLab/Pat/Experiments/Time course assays/03112022_Time-course assay/10readings/onlyPatstrains/", pattern = "TCA*") 
annotation <- createAnnotation(yourFlowSet = plate_03112022)
write.csv(annotation,'~/Google Drive/Shared drives/PlantSynBioLab/Pat/Experiments/Time course assays/03112022_Time-course assay/03112022_Time-course assay_10platesPatStrains2.csv')
annotation <- read.csv('~/Google Drive/Shared drives/PlantSynBioLab/Pat/Experiments/Time course assays/03112022_Time-course assay/03112022_Time-course assay_10platesPatStrains2.csv')
aplate_03112022 <- annotateFlowSet(yourFlowSet = plate_03112022, annotation_df = annotation, mergeBy = 'name')
head(rownames(pData(aplate_03112022)))
head(pData(aplate_03112022))

write.flowSet(aplate_03112022, outdir = "flowSets/dual-time-course")
aplate_03112022 <-
  read.flowSet(path = "flowSets/dual-time-course/", phenoData = "annotation.txt")
plate_03112022_sum <- summarizeFlow(aplate_03112022, gated = TRUE)
[1] "Summarizing all events..."
plate_03112022_sum <-
  plate_03112022_sum %>% mutate(
    background_p = case_when(
      strain %in% c("yWL185", "yWL186") ~ "W303",
      strain %in% c("yWL209", "yWL210") ~ "YPH499"
    ),
    receptor_p = case_when(
      strain %in% c("yWL185", "yWL209") ~ "TIR1",
      strain %in% c("yWL186", "yWL210") ~ "AFB2"
    )
  )
#The time auxin addition is equal to time zero
time0 <-
  "303112022-Pat-TCA03_Time-course assay_Auxin_yWL185-C1.fcs"
# or whatever well was being read when auxin was added

plate_03112022_sum$time <-
  plate_03112022_sum$btime - 
  plate_03112022_sum[[which(plate_03112022_sum$name == time0), "btime"]]
#single bracket -->extracting the all name, 2 brackets extract just single "value" or "values"
#To normalize data

plate_03112022_sum <-
  plate_03112022_sum %>% mutate(ratio = BL1.Amean/YL1.Amean) %>%
  group_by(background_p, receptor_p) %>% 
  mutate(normalizedratio = ratio/mean(ratio))
ratio <- 
  ggplot(data = subset(plate_03112022_sum), 
         aes(x = time, y = normalizedratio,  
             group = interaction(factor(colony), factor(treatment)), 
             linetype =  factor(treatment), shape = factor(treatment), 
             color = factor(treatment))) +
  geom_point(aes(color = treatment), size = 2) + 
  geom_line(aes(color = treatment), linewidth= 1)  + 
  xlab("Time post auxin addition (min)") + 
  scale_shape_manual(values = c(19, 1)) + 
  ylab("Normalized Venus/mScarlet-I") + 
  facet_grid(background_p~receptor_p) +
  scale_color_manual(values = c("#5499C7", "#999999")) + 
  theme_base() + 
  theme(legend.position = "none", 
        panel.grid.minor = element_line(linewidth = 0.3, 
                                        linetype = 'solid', 
                                        colour = "white"), 
        axis.line = element_line(colour = "black", 
                                 linewidth = 1, linetype = "solid")) 
ratio

Without normalization

ratio_raw <- 
  ggplot(data = subset(plate_03112022_sum), 
         aes(x = time, y = ratio,  
             group = interaction(factor(colony), factor(treatment)), 
             linetype =  factor(treatment), shape = factor(treatment), 
             color = factor(treatment))) +
  geom_point(aes(color = treatment), size = 2) + 
  geom_line(aes(color = treatment), linewidth= 1)  + 
  xlab("Time post auxin addition (min)") + 
  scale_shape_manual(values = c(19, 1)) + 
  ylab("Venus/mScarlet-I") + 
  facet_grid(background_p~receptor_p, scales = "free") +
  scale_color_manual(values = c("#5499C7", "#999999")) + 
  theme_base() + 
  theme(legend.position = "none", 
        panel.grid.minor = element_line(linewidth = 0.3, 
                                        linetype = 'solid', 
                                        colour = "white"), 
        axis.line = element_line(colour = "black", 
                                 linewidth = 1, linetype = "solid")) 
ratio_raw

ratio_raw / ratio + plot_annotation(tag_levels = "A") & theme(plot.background = element_blank())
ggsave("tc-strains.pdf", width = 5, height = 7)
ggsave("tc-strains.png", width = 5, height = 7)

CV plot

Using the above time course dataset we can compare coefficients of variation in the individual parameters and the ratio for each of the strains and biosensors at steady state.

yWL185 (TIR1 dual-fusion, W303 yeast)


data185 <- steadyState(aplate_03112022, gated = TRUE)
[1] "No further gating applied."
[1] "Converting events..."
data185 <- subset(data185, strain == "yWL185" & name %in% c("803112022-Pat-TCA08_Time-course assay_Auxin_yWL185-C1.fcs", "803112022-Pat-TCA08_Time-course assay_Control_yWL185-C1.fcs" ))

cv <- function(x) return(round(sd(x)/mean(x),2))


data185 <- subset(data185, BL1.A >1 & YL1.A > 1)
data185$FLratio <- data185$BL1.A/data185$YL1.A
range(data185$BL1.A)
[1]      45 1048575
cv <- function(x) return(round(sd(x)/mean(x),2))

data185$Venus <- data185$BL1.A / median(data185$BL1.A)
data185$mScarlet <- data185$YL1.A / median(data185$YL1.A)
data185$FLratio <- data185$BL1.A / data185$YL1.A
data185$ratio <- data185$FLratio / median(data185$FLratio)



data_long185 <- data185 %>% 
  dplyr::select(treatment, Venus, mScarlet, ratio, strain) %>%
  pivot_longer(cols = c(Venus, mScarlet, ratio), 
               names_to = "parameter", 
               values_to = "value") %>%
  dplyr::mutate(parameter = fct_relevel(parameter, "Venus")) 

# need to also format CVs approriately for annotating

CV185 <-
  data185 %>% group_by(treatment) %>% 
  dplyr::summarise(across(dplyr::where(is_double), cv)) %>%
  dplyr::select(treatment, Venus, mScarlet, ratio) %>%
  pivot_longer(
    cols = c(Venus, mScarlet, ratio),
    names_to = "parameter",
    values_to = "value"
  )

#data185

plot185 <- ggplot(data = data_long185, 
       mapping = aes(x = value, 
                     color = treatment)) + 
  geom_density() + xlim(c(-1,4)) + 
  labs(x = "median normalized intensity", color = "treatment")  + theme_test() + 
  geom_text(data = subset(CV185, treatment == "50 uM Auxin"), 
             aes(label = paste0("CV = ", value)),
             x = 2, y = 1) + 
  geom_text(data = subset(CV185, treatment == "Control"), 
             aes(label = paste0("CV = ", value)), 
            x = 0, y = 1) + 
  scale_color_viridis_d(option = "D", end = .75, direction = -1) 




venus185 <- ggplot(data185, aes(x=data185$Venus, group=treatment, fill=treatment, color= treatment)) + geom_density(adjust=1.5, alpha=.5) + labs(x = "Venus", y ="Density") + xlim(-0.1,2)+ ylim(0,2) + theme_classic() +  theme(legend.position="none")  + geom_text(data = subset(CV185, parameter == "Venus" & treatment == "50 uM Auxin"), aes(label = paste0("CV = ", value)),
             x = 1.2, y = 1.1) + 
  geom_text(data = subset(CV185, parameter == "Venus"& treatment == "Control"), 
             aes(label = paste0("CV = ", value)), 
            x = 0.55, y = 1.5) + scale_color_manual(values=c("#F1C40F", "#626567")) + scale_fill_manual(values=c("#F1C40F", "#626567"))
#venus185

red185 <- ggplot(data185, aes(x=data185$mScarlet, group=treatment, fill=treatment, color= treatment)) + geom_density(adjust=1.5, alpha=.5) + labs(x = "mScarlet", y ="Density") + xlim(-0.1,2) + ylim(0,2) + theme_classic() +  theme(legend.position="none")  + geom_text(data = subset(CV185, parameter == "mScarlet" & treatment == "50 uM Auxin"), aes(label = paste0("CV = ", value)),
             x = 1.2, y = 1.1) + 
  geom_text(data = subset(CV185, parameter == "mScarlet"& treatment == "Control"), 
             aes(label = paste0("CV = ", value)), 
            x = 0.55, y = 1.5) + scale_color_manual(values=c("#CB4335", "#626567")) + scale_fill_manual(values=c("#CB4335", "#626567"))
#red185


ratio185<- ggplot(data185, aes(x=data185$ratio, group=treatment, fill=treatment, color= treatment)) + geom_density(adjust=1.5, alpha=.5)  +labs(x = "Venus/mScarlet ratio", y ="Density") + xlim(-0.1,2) + ylim(0,3.5) + theme_classic() +  theme(legend.position="none")   +  geom_text(data = subset(CV185, parameter == "ratio" & treatment == "50 uM Auxin"), aes(label = paste0("CV = ", value)),
             x = 0.4, y = 2) + 
  geom_text(data = subset(CV185, parameter == "ratio"& treatment == "Control"), 
             aes(label = paste0("CV = ", value)), 
            x = 1.6, y = 2) + scale_color_manual(values=c("#5499C7", "#626567")) + scale_fill_manual(values=c("#5499C7", "#626567"))

#ratio185

plot185 <- grid.arrange(venus185, red185, ratio185, nrow=3, ncol=1)

plot185
TableGrob (3 x 1) "arrange": 3 grobs

yWL186 (AFB2 dual-fusion, W303 yeast)

data186 <- steadyState(aplate_03112022, gated = TRUE)
[1] "No further gating applied."
[1] "Converting events..."
data186 <- subset(data186, strain == "yWL186" & name %in% c("803112022-Pat-TCA08_Time-course assay_Auxin_yWL186-C1.fcs", "803112022-Pat-TCA08_Time-course assay_Control_yWL186-C1.fcs" ))

cv <- function(x) return(round(sd(x)/mean(x),2))


data186 <- subset(data186, BL1.A >1 & YL1.A > 1)
data186$FLratio <- data186$BL1.A/data186$YL1.A
range(data186$BL1.A)
[1]      25 1048575
cv <- function(x) return(round(sd(x)/mean(x),2))

data186$Venus <- data186$BL1.A / median(data186$BL1.A)
data186$mScarlet <- data186$YL1.A / median(data186$YL1.A)
data186$FLratio <- data186$BL1.A / data186$YL1.A
data186$ratio <- data186$FLratio / median(data186$FLratio)



data_long186 <- data186 %>% 
  dplyr::select(treatment, Venus, mScarlet, ratio, strain) %>%
  pivot_longer(cols = c(Venus, mScarlet, ratio), 
               names_to = "parameter", 
               values_to = "value") %>%
  dplyr::mutate(parameter = fct_relevel(parameter, "Venus")) 

# need to also format CVs approriately for annotating

CV186 <-
  data186 %>% group_by(treatment) %>% 
  dplyr::summarise(across(dplyr::where(is_double), cv)) %>%
  dplyr::select(treatment, Venus, mScarlet, ratio) %>%
  pivot_longer(
    cols = c(Venus, mScarlet, ratio),
    names_to = "parameter",
    values_to = "value"
  )

#data186

plot186 <- ggplot(data = data_long186, 
       mapping = aes(x = value, 
                     color = treatment)) + 
  geom_density() + xlim(c(-1,4)) + 
  labs(x = "median normalized intensity", color = "treatment")  + theme_test() + 
  geom_text(data = subset(CV186, treatment == "50 uM Auxin"), 
             aes(label = paste0("CV = ", value)),
             x = 2, y = 1) + 
  geom_text(data = subset(CV186, treatment == "Control"), 
             aes(label = paste0("CV = ", value)), 
            x = 0, y = 1) + 
  scale_color_viridis_d(option = "D", end = .75, direction = -1) 



venus186 <- ggplot(data186, aes(x=data186$Venus, group=treatment, fill=treatment, color = treatment)) + geom_density(adjust=1.5, alpha=.4) + labs(x = "Venus (normalized median)", y ="Density") + xlim(0,2)+ ylim(0,2) + theme_classic() +  theme(legend.position="none") + geom_text(data = subset(CV186, parameter == "Venus" & treatment == "50 uM Auxin"), aes(label = paste0("CV = ", value)),
             x = 1.2, y = 1.1) + 
  geom_text(data = subset(CV186, parameter == "Venus"& treatment == "Control"), 
             aes(label = paste0("CV = ", value)), 
            x = 0.55, y = 1.5) + scale_color_manual(values=c("#F1C40F", "#626567")) + scale_fill_manual(values=c("#F1C40F", "#626567"))


red186 <- ggplot(data186, aes(x=data186$mScarlet, group=treatment, fill=treatment, color = treatment)) + geom_density(adjust=1.5, alpha=.4) + labs(x = "mScarlet (normalized median)", y ="Density") + xlim(0,2) + ylim(0,2) + theme_classic() +  theme(legend.position="none") +  scale_fill_manual(values=c("#EC7063", "#999999")) + geom_text(data = subset(CV186, parameter == "mScarlet" & treatment == "50 uM Auxin"), aes(label = paste0("CV = ", value)),
             x = 1.2, y = 1.1) + 
  geom_text(data = subset(CV186, parameter == "mScarlet"& treatment == "Control"), 
             aes(label = paste0("CV = ", value)), 
            x = 0.55, y = 1.5) + scale_color_manual(values=c("#CB4335", "#626567")) + scale_fill_manual(values=c("#CB4335", "#626567"))


ratio186<- ggplot(data186, aes(x=data186$ratio, group=treatment, fill=treatment, color = treatment)) + geom_density(adjust=1.5, alpha=.4)  +labs(x = "Venus/mScarlet ratio", y ="Density") + xlim(0,2) + ylim(0,3.5) + theme_classic() +  theme(legend.position="none")   +  geom_text(data = subset(CV186, parameter == "ratio" & treatment == "50 uM Auxin"), aes(label = paste0("CV = ", value)),
             x = 0.2, y = 2) + 
  geom_text(data = subset(CV186, parameter == "ratio"& treatment == "Control"), 
             aes(label = paste0("CV = ", value)), 
            x = 1.3, y = 2) + scale_color_manual(values=c("#5499C7", "#626567")) + scale_fill_manual(values=c("#5499C7", "#626567"))

plot186 <- grid.arrange(venus186, red186, ratio186, nrow=3, ncol=1)

plot186
TableGrob (3 x 1) "arrange": 3 grobs

yWL209 (TIR1 dual-fusion, YPH499 yeast)


data209 <- steadyState(aplate_03112022, gated = TRUE)
[1] "No further gating applied."
[1] "Converting events..."
data209 <- subset(data209, strain == "yWL209" & name %in% c("803112022-Pat-TCA08_Time-course assay_Auxin_yWL209-C1.fcs", "803112022-Pat-TCA08_Time-course assay_Control_yWL209-C1.fcs" ))

cv <- function(x) return(round(sd(x)/mean(x),2))


data209 <- subset(data209, BL1.A >1 & YL1.A > 1)
data209$FLratio <- data209$BL1.A/data209$YL1.A
range(data209$BL1.A)
[1]       9 1048575
cv <- function(x) return(round(sd(x)/mean(x),2))

data209$Venus <- data209$BL1.A / median(data209$BL1.A)
data209$mScarlet <- data209$YL1.A / median(data209$YL1.A)
data209$FLratio <- data209$BL1.A / data209$YL1.A
data209$ratio <- data209$FLratio / median(data209$FLratio)



data_long209 <- data209 %>% 
  dplyr::select(treatment, Venus, mScarlet, ratio, strain) %>%
  pivot_longer(cols = c(Venus, mScarlet, ratio), 
               names_to = "parameter", 
               values_to = "value") %>%
  dplyr::mutate(parameter = fct_relevel(parameter, "Venus")) 

# need to also format CVs approriately for annotating

CV209 <-
  data209 %>% group_by(treatment) %>% 
  dplyr::summarise(across(dplyr::where(is_double), cv)) %>%
  dplyr::select(treatment, Venus, mScarlet, ratio) %>%
  pivot_longer(
    cols = c(Venus, mScarlet, ratio),
    names_to = "parameter",
    values_to = "value"
  )

#data209

plot209 <- ggplot(data = data_long209, 
       mapping = aes(x = value, 
                     color = treatment)) + 
  geom_density() + xlim(c(-1,4)) + 
  labs(x = "median normalized intensity", color = "treatment")  + theme_test() + 
  geom_text(data = subset(CV209, treatment == "50 uM Auxin"), 
             aes(label = paste0("CV = ", value)),
             x = 1.2, y = 1) + 
  geom_text(data = subset(CV209, treatment == "Control"), 
             aes(label = paste0("CV = ", value)), 
            x = 0, y = 1) + 
  scale_color_viridis_d(option = "D", end = .75, direction = -1) 




venus209 <- ggplot(data209, aes(x=data209$Venus, group=treatment, fill=treatment, color = treatment)) + geom_density(adjust=1.5, alpha=.4) + labs(x = "Venus", y ="Density") + xlim(0,2)+ ylim(0,2) + theme_classic() +  theme(legend.position="none")  + geom_text(data = subset(CV209, parameter == "Venus" & treatment == "50 uM Auxin"), aes(label = paste0("CV = ", value)),
             x = 1.2, y = 1.1) + 
  geom_text(data = subset(CV209, parameter == "Venus"& treatment == "Control"), 
             aes(label = paste0("CV = ", value)), 
            x = 0.55, y = 1.5) + scale_color_manual(values=c("#F1C40F", "#626567")) + scale_fill_manual(values=c("#F1C40F", "#626567"))


red209 <- ggplot(data209, aes(x=data209$mScarlet, group=treatment, fill=treatment, color = treatment)) + geom_density(adjust=1.5, alpha=.4) + labs(x = "mScarlet", y ="Density") + xlim(0,2) + ylim(0,2) + theme_classic() +  theme(legend.position="none")  + geom_text(data = subset(CV209, parameter == "mScarlet" & treatment == "50 uM Auxin"), aes(label = paste0("CV = ", value)),
             x = 1.2, y = 1.1) + 
  geom_text(data = subset(CV209, parameter == "mScarlet"& treatment == "Control"), 
             aes(label = paste0("CV = ", value)), 
            x = 0.55, y = 1.5) + scale_color_manual(values=c("#CB4335", "#626567")) + scale_fill_manual(values=c("#CB4335", "#626567"))


ratio209<- ggplot(data209, aes(x=data209$ratio, group=treatment, fill=treatment, color = treatment)) + geom_density(adjust=1.5, alpha=.4)  +labs(x = "Venus/mScarlet ratio", y ="Density") + xlim(0,2) + ylim(0,3.5) + theme_classic() +  theme(legend.position="none")   +  geom_text(data = subset(CV209, parameter == "ratio" & treatment == "50 uM Auxin"), aes(label = paste0("CV = ", value)),
             x = 0.3, y = 2) + 
  geom_text(data = subset(CV209, parameter == "ratio"& treatment == "Control"), 
             aes(label = paste0("CV = ", value)), 
            x = 1.6, y = 2) + scale_color_manual(values=c("#5499C7", "#626567")) + scale_fill_manual(values=c("#5499C7", "#626567"))


plot209 <- grid.arrange(venus209, red209, ratio209, nrow=3, ncol=1)

plot209
TableGrob (3 x 1) "arrange": 3 grobs

yWL210 (AFB2 dual-fusion, YPH499 yeast)


data210 <- steadyState(aplate_03112022, gated = TRUE)
[1] "No further gating applied."
[1] "Converting events..."
#data <- tidyFlow(aplate_20210619_W303)

data210 <- subset(data210, strain == "yWL210" & name %in% c("803112022-Pat-TCA08_Time-course assay_Auxin_yWL210-C1.fcs", "803112022-Pat-TCA08_Time-course assay_Control_yWL210-C1.fcs" ))

cv <- function(x) return(round(sd(x)/mean(x),2))


data210 <- subset(data210, BL1.A >1 & YL1.A > 1)
data210$FLratio <- data210$BL1.A/data210$YL1.A
range(data210$BL1.A)
[1]      25 1048575
cv <- function(x) return(round(sd(x)/mean(x),2))

data210$Venus <- data210$BL1.A / median(data210$BL1.A)
data210$mScarlet <- data210$YL1.A / median(data210$YL1.A)
data210$FLratio <- data210$BL1.A / data210$YL1.A
data210$ratio <- data210$FLratio / median(data210$FLratio)



data_long210 <- data210 %>% 
  dplyr::select(treatment, Venus, mScarlet, ratio, strain) %>%
  pivot_longer(cols = c(Venus, mScarlet, ratio), 
               names_to = "parameter", 
               values_to = "value") %>%
  dplyr::mutate(parameter = fct_relevel(parameter, "Venus")) 

# need to also format CVs approriately for annotating

CV210 <-
  data210 %>% group_by(treatment) %>% 
  dplyr::summarise(across(dplyr::where(is_double), cv)) %>%
  dplyr::select(treatment, Venus, mScarlet, ratio) %>%
  pivot_longer(
    cols = c(Venus, mScarlet, ratio),
    names_to = "parameter",
    values_to = "value"
  )

#data210

plot210 <- ggplot(data = data_long210, 
       mapping = aes(x = value, 
                     color = treatment)) + 
  geom_density() + xlim(c(-1,4)) + 
  labs(x = "median normalized intensity", color = "treatment")  + theme_test() + 
  geom_text(data = subset(CV210, treatment == "50 uM Auxin"), 
             aes(label = paste0("CV = ", value)),
             x = 2, y = 1) + 
  geom_text(data = subset(CV210, treatment == "Control"), 
             aes(label = paste0("CV = ", value)), 
            x = 0, y = 1) + 
  scale_color_viridis_d(option = "D", end = .75, direction = -1) +
  facet_grid(parameter~.) 




venus210 <- ggplot(data210, aes(x=data210$Venus, group=treatment,color=treatment,  fill=treatment)) + geom_density(adjust=1.5, alpha=.4) + labs(x = "Venus", y ="Density") + xlim(0,2)+ ylim(0,2) + theme_classic() +  theme(legend.position="none") +  geom_text(data = subset(CV210, parameter == "Venus" & treatment == "50 uM Auxin"), aes(label = paste0("CV = ", value)),
             x = 1.5, y = 1) + 
  geom_text(data = subset(CV210, parameter == "Venus"& treatment == "Control"), 
             aes(label = paste0("CV = ", value)), 
            x = 0.7, y = 1.5) + scale_color_manual(values=c("#F1C40F", "#626567")) + scale_fill_manual(values=c("#F1C40F", "#626567"))


red210 <- ggplot(data210, aes(x=data210$mScarlet, group=treatment,color=treatment,  fill=treatment)) + geom_density(adjust=1.5, alpha=.4) + labs(x = "mScarlet", y ="Density") + xlim(0,2) + ylim(0,2) + theme_classic() +  theme(legend.position="none") + geom_text(data = subset(CV210, parameter == "mScarlet" & treatment == "50 uM Auxin"), aes(label = paste0("CV = ", value)),
             x = 1.2, y = 1.2) + 
  geom_text(data = subset(CV210, parameter == "mScarlet"& treatment == "Control"), 
             aes(label = paste0("CV = ", value)), 
            x = 0.4, y = 1.5) + scale_color_manual(values=c("#CB4335", "#626567")) + scale_fill_manual(values=c("#CB4335", "#626567"))


ratio210<- ggplot(data210, aes(x=data210$ratio, group=treatment, color=treatment, fill = treatment)) + geom_density(adjust=1.5, alpha=.4)  +labs(x = "Venus/mScarlet ratio", y ="Density") + xlim(0,2) + ylim(0,3.5) + theme_classic() +  theme(legend.position="none")  + geom_text(data = subset(CV210, parameter == "ratio" & treatment == "50 uM Auxin"), aes(label = paste0("CV = ", value)),
             x = 0.2, y = 1.8) + 
  geom_text(data = subset(CV210, parameter == "ratio"& treatment == "Control"), 
             aes(label = paste0("CV = ", value)), 
            x = 1.6, y = 1.8) + scale_color_manual(values=c("#5499C7", "#626567")) + scale_fill_manual(values=c("#5499C7", "#626567"))
#ratio210

plot210 <- grid.arrange(venus210, red210, ratio210, nrow=3, ncol=1)

plot210
TableGrob (3 x 1) "arrange": 3 grobs
dual_fusion_cv <- (venus210 + ggtitle("AFB2")+ 
                theme(plot.title = element_text(hjust = 0.5)) | 
                venus209 + ggtitle("TIR1") + 
                theme(plot.title = element_text(hjust = 0.5))) / 
               (red210 | red209) / 
             (ratio210 | ratio209) + 
  theme(title = element_text(hjust = 0))
dual_fusion_cv 
ggsave("dual_fusion_cv.pdf", width = 6.3, height = 6)
ggsave("dual_fusion_cv.png", width = 6.3, height = 6)

Single-fusion vs dual-fusion comparison in W303 yeast strain

plate_20210619_W303 <- read.plateSet(path = "~/Google Drive/Shared drives/PlantSynBioLab/Pat/Experiments/Time course assays/20210619/W303only/", pattern = "r*") 
annotation <- createAnnotation(yourFlowSet = plate_20210619_W303)
write.csv(annotation,'/Users/patchaisupa/Google Drive/Shared drives/PlantSynBioLab/Pat/Experiments/Time course assays/20210619/20210619_W303only_annotation.csv')
annotation <- read.csv('~/Google Drive/Shared drives/PlantSynBioLab/Pat/Experiments/Time course assays/20210619/20210619_W303only_annotation.csv')
aplate_20210619_W303 <- annotateFlowSet(yourFlowSet = plate_20210619_W303, annotation_df = annotation, mergeBy = 'name')
head(rownames(pData(aplate_20210619_W303)))
head(pData(aplate_20210619_W303))
write.flowSet(aplate_20210619_W303, outdir = "flowSets/design-relative-expression")
aplate_20210619_W303 <- read.flowSet(path = "flowSets/design-relative-expression/", phenoData = "annotation.txt")
plate_20210619_W303_sum <- summarizeFlow(aplate_20210619_W303,  gated = TRUE)
[1] "Summarizing all events..."
#The time auxin addition is equal to time zero
time0 <- "4E01.fcs" 
# or whatever well was being read when auxin was added

plate_20210619_W303_sum$time <- plate_20210619_W303_sum$btime-plate_20210619_W303_sum[[which(plate_20210619_W303_sum$name == time0), "btime"]]
#single bracket -->extracting the all name, 2 brackets extract just single "value" or "values"
plate_20210619_W303_sum <- plate_20210619_W303_sum %>%
  mutate(
    design = case_when(
      strain %in% c("yWL185","yWL186") ~ "dual-fusion",
    strain %in% c("yWL161","yWL162") ~ "single-fusion"), 
         fbox = case_when(
    strain %in% c("yWL161","yWL185") ~ "TIR1",
    strain %in% c("yWL162","yWL186") ~ "AFB2")) %>%
  mutate(design_construct = paste(fbox, design)) 

plate_20210619_W303_sum <-
  plate_20210619_W303_sum %>% mutate(ratio = FL1.Amean/FL4.Amean) %>%
  group_by(design, fbox) %>% 
  mutate(normalizedratio = ratio/mean(ratio))

plate_20210619_W303_sum<-
  plate_20210619_W303_sum %>% mutate(green = FL1.Amean) %>%
  group_by(design, fbox) %>% 
  mutate(normalized_Greenexpression = FL1.Amean/mean(FL1.Amean))

plate_20210619_W303_sum <-
  plate_20210619_W303_sum %>% mutate(red = FL4.Amean) %>%
  group_by(design, fbox) %>% 
  mutate(normalized_Redexpression = FL4.Amean/mean(FL4.Amean))
TIR1_single <- qplot(x = time, y = FL1.Amean/FL4.Amean, data = subset(plate_20210619_W303_sum, strain =="yWL161"), group = factor(treatment), linetype =  factor(treatment), shape = factor(treatment), color = factor(treatment)) +
  xlab("Time (min)") +
  geom_point(aes(color = treatment, shape = treatment), size = 1) + geom_line(aes(color = treatment, shape = treatment), linewidth = 0.5)  +  scale_shape_manual(values = c(19, 1)) + ylab("Venus/Scarlet ratio") + scale_color_manual(values = c("#5499C7", "#626567")) + theme_minimal() + theme(legend.position = "none", panel.grid.major = element_line(linewidth = 0.3, linetype = 'solid', colour = "white"), panel.grid.minor = element_line(linewidth = 0.3, linetype = 'solid', colour = "white")) +facet_wrap(~design_construct, scale ="free_y") 


AFB2_single <- qplot(x = time, y = FL1.Amean/FL4.Amean, data = subset(plate_20210619_W303_sum, strain =="yWL162"), group = factor(treatment), linetype =  factor(treatment), shape = factor(treatment), color = factor(treatment)) +
   xlab("Time (min)") +
  geom_point(aes(color = treatment, shape = treatment), size = 1) + geom_line(aes(color = treatment, shape = treatment), linewidth = 0.5)  + scale_shape_manual(values = c(19, 1)) + ylab("Venus/Scarlet ratio") + scale_color_manual(values = c("#5499C7", "#626567")) + theme_minimal() + theme(legend.position = "none",  panel.grid.major = element_line(linewidth = 0.3, linetype = 'solid', colour = "white"), panel.grid.minor = element_line(linewidth = 0.3, linetype = 'solid', colour = "white")) +facet_wrap(~design_construct, scale ="free_y") 

TIR1_dual <- qplot(x = time, y = FL1.Amean/FL4.Amean, data = subset(plate_20210619_W303_sum, strain =="yWL185"), group = factor(treatment), linetype =  factor(treatment), shape = factor(treatment), color = factor(treatment)) +
  geom_point(aes(color = treatment, shape = treatment), size = 1) + geom_line(aes(color = treatment, shape = treatment), linewidth = 0.5)  + xlab("Time (min)") + scale_shape_manual(values = c(19, 1)) + ylab("Venus/Scarlet ratio") + scale_color_manual(values = c("#5499C7", "#626567")) + theme_minimal() + theme(legend.position = "none", panel.grid.major = element_line(linewidth = 0.3, linetype = 'solid', colour = "white"), panel.grid.minor = element_line(linewidth = 0.3, linetype = 'solid', colour = "white")) +facet_wrap(~design_construct, scale ="free_y") 

AFB2_dual <- qplot(x = time, y = FL1.Amean/FL4.Amean, data = subset(plate_20210619_W303_sum, strain =="yWL186"), group = factor(treatment), linetype =  factor(treatment), shape = factor(treatment), color = factor(treatment)) +
   xlab("Time (min)") +
  geom_point(aes(color = treatment, shape = treatment), size = 1) + geom_line(aes(color = treatment, shape = treatment), linewidth = 0.5)  + scale_shape_manual(values = c(19, 1)) + ylab("Venus/Scarlet ratio") + scale_color_manual(values = c("#5499C7", "#626567")) + theme_minimal() + theme(legend.position = "none", panel.grid.major = element_line(linewidth = 0.3, linetype = 'solid', colour = "white"), panel.grid.minor = element_line(linewidth = 0.3, linetype = 'solid', colour = "white")) +facet_wrap(~design_construct, scale ="free_y") 

grid.arrange(AFB2_single, TIR1_single, TIR1_dual, AFB2_dual, nrow=2, ncol=4)

W303ratio <- qplot(x = time, y = normalizedratio, data = subset(plate_20210619_W303_sum), group = factor(treatment), linetype =  factor(treatment), shape = factor(treatment), color = factor(treatment)) + xlab("Time (min)") +
  geom_point(aes(color = treatment), size = 0.5) + geom_line(aes(color = treatment), linewidth = 1)  +  scale_shape_manual(values = c(19, 1)) + ylab("Venus") + scale_color_manual(values = c("#2E86C1", "#626567"))  + theme_minimal() + theme(legend.position = "bottom",  panel.grid.major = element_line(linewidth = 0.3, linetype = 'solid', colour = "white"), panel.grid.minor = element_line(linewidth = 0.3, linetype = 'solid', colour = "white"), axis.line = element_line(colour = "black", 
                      linewidth = 1, linetype = "solid")) + facet_wrap(~design_construct, scale ="free_y")

W303venus <- qplot(x = time, y = normalized_Greenexpression, data = subset(plate_20210619_W303_sum), group = factor(treatment), linetype =  factor(treatment), shape = factor(treatment), color = factor(treatment)) + xlab("Time (min)") +
  geom_point(aes(color = treatment), size = 0.5) + geom_line(aes(color = treatment), linewidth = 1)  +  scale_shape_manual(values = c(19, 1)) + ylab("Venus/Scarlet") + scale_color_manual(values = c("#F1C40F", "#626567"))  + theme_minimal() + theme(legend.position = "bottom",  panel.grid.major = element_line(linewidth = 0.3, linetype = 'solid', colour = "white"), panel.grid.minor = element_line(linewidth = 0.3, linetype = 'solid', colour = "white"), axis.line = element_line(colour = "black", 
                      linewidth = 1, linetype = "solid")) + facet_wrap(~design_construct, scale ="free_y")

grid.arrange(W303venus, W303ratio, nrow=2, ncol=2)

Venus_aov <- aov(FL1.Amean ~ design_construct * treatment * before_after, 
  data = plate_20210619_W303_sum %>%
  dplyr::filter(time <= 0 | time >= 200))
summary(Venus_aov)
                                        Df    Sum Sq   Mean Sq F value   Pr(>F)    
design_construct                         3 5.902e+09 1.967e+09 108.760  < 2e-16 ***
treatment                                1 9.695e+08 9.695e+08  53.601 5.82e-09 ***
before_after                             1 4.570e+06 4.570e+06   0.253    0.618    
design_construct:treatment               3 5.293e+07 1.764e+07   0.976    0.414    
design_construct:before_after            3 9.180e+07 3.060e+07   1.692    0.184    
treatment:before_after                   1 6.641e+08 6.641e+08  36.715 3.56e-07 ***
design_construct:treatment:before_after  3 3.063e+07 1.021e+07   0.564    0.642    
Residuals                               41 7.416e+08 1.809e+07                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Venus_HSD.test <- 
    agricolae::HSD.test(Venus_aov, 
                        trt = c("design_construct", 
                                "treatment", 
                                "before_after"), 
                        console = TRUE))

Study: Venus_aov ~ c("design_construct", "treatment", "before_after")

HSD Test for FL1.Amean 

Mean Square Error:  18087298 

design_construct:treatment:before_after,  means

Alpha: 0.05 ; DF Error: 41 
Critical Value of Studentized Range: 5.154955 

Groups according to probability of means differences and alpha level( 0.05 )

Treatments with the same letter are not significantly different.
$statistics
   MSerror Df     Mean       CV
  18087298 41 49475.37 8.596028

$parameters
   test                                  name.t ntr StudentizedRange alpha
  Tukey design_construct:treatment:before_after  16         5.154955  0.05

$means
                                       FL1.Amean      std r      Min      Max      Q25      Q50      Q75
AFB2 dual-fusion:Auxin:after            24425.97 3887.943 4 19046.09 27855.18 22934.16 25401.31 26893.13
AFB2 dual-fusion:Auxin:before           34631.51 2164.181 3 33214.07 37122.60 33385.97 33557.87 35340.23
AFB2 dual-fusion:Control EtOH:after     43943.78 2563.443 4 40314.31 46305.36 43299.85 44577.73 45221.67
AFB2 dual-fusion:Control EtOH:before    35281.28  747.563 3 34785.81 36141.17 34851.33 34916.85 35529.01
AFB2 single-fusion:Auxin:after          48152.32 8233.437 4 41566.06 58870.26 41748.87 46086.48 52489.94
AFB2 single-fusion:Auxin:before         52801.44 3789.368 3 49120.11 56690.32 50856.99 52593.87 54642.10
AFB2 single-fusion:Control EtOH:after   61495.06 1241.776 4 59958.17 62859.15 60845.16 61581.46 62231.36
AFB2 single-fusion:Control EtOH:before  53911.90 2286.620 3 51418.04 55909.91 52912.90 54407.76 55158.83
TIR1 dual-fusion:Auxin:after            41225.93 2818.571 4 37362.85 43733.63 40076.43 41903.61 43053.11
TIR1 dual-fusion:Auxin:before           46003.40 1595.801 3 44645.69 47761.17 45124.52 45603.34 46682.25
TIR1 dual-fusion:Control EtOH:after     53108.52 5964.120 4 46969.08 60966.52 49652.60 52249.25 55705.17
TIR1 dual-fusion:Control EtOH:before    44671.84 1768.004 3 43508.04 46706.33 43654.60 43801.16 45253.75
TIR1 single-fusion:Auxin:after          53550.99 3388.730 4 50475.84 58381.61 51941.54 52673.26 54282.71
TIR1 single-fusion:Auxin:before         63962.75 3201.204 3 61073.09 67403.85 62242.20 63411.32 65407.59
TIR1 single-fusion:Control EtOH:after   65619.10 7089.748 5 53646.79 71126.31 64830.36 68765.73 69726.29
TIR1 single-fusion:Control EtOH:before  64865.95 3237.883 3 61178.65 67245.10 63676.38 66174.10 66709.60

$comparison
NULL

$groups
                                       FL1.Amean groups
TIR1 single-fusion:Control EtOH:after   65619.10      a
TIR1 single-fusion:Control EtOH:before  64865.95     ab
TIR1 single-fusion:Auxin:before         63962.75     ab
AFB2 single-fusion:Control EtOH:after   61495.06     ab
AFB2 single-fusion:Control EtOH:before  53911.90     bc
TIR1 single-fusion:Auxin:after          53550.99     bc
TIR1 dual-fusion:Control EtOH:after     53108.52     bc
AFB2 single-fusion:Auxin:before         52801.44    bcd
AFB2 single-fusion:Auxin:after          48152.32     cd
TIR1 dual-fusion:Auxin:before           46003.40    cde
TIR1 dual-fusion:Control EtOH:before    44671.84    cde
AFB2 dual-fusion:Control EtOH:after     43943.78    cde
TIR1 dual-fusion:Auxin:after            41225.93     de
AFB2 dual-fusion:Control EtOH:before    35281.28     ef
AFB2 dual-fusion:Auxin:before           34631.51     ef
AFB2 dual-fusion:Auxin:after            24425.97      f

attr(,"class")
[1] "group"
Venus_groups <- Venus_HSD.test$groups %>% 
  as_tibble(rownames = "names") %>%
  separate(col = names, into = c("design_construct", 
                                "treatment", 
                                "before_after"), 
           sep = "\\:", remove = FALSE) %>% 
  left_join(Venus_HSD.test$means %>% 
              as_tibble(rownames = "names") %>% 
              dplyr::select(c(names, Max)), 
            by = "names") %>%
  mutate(treatment = fct_rev(treatment), 
         before_after = fct_rev(before_after))
mScarlet_aov <- aov(FL4.Amean ~ design_construct * treatment * before_after, 
  data = plate_20210619_W303_sum %>%
  dplyr::filter(time <= 0 | time >= 200))
summary(mScarlet_aov)
                                        Df    Sum Sq   Mean Sq  F value   Pr(>F)    
design_construct                         3 1.318e+10 4.393e+09 1152.935  < 2e-16 ***
treatment                                1 2.843e+06 2.843e+06    0.746  0.39279    
before_after                             1 7.962e+07 7.962e+07   20.894 4.41e-05 ***
design_construct:treatment               3 4.175e+06 1.392e+06    0.365  0.77844    
design_construct:before_after            3 6.634e+07 2.211e+07    5.803  0.00211 ** 
treatment:before_after                   1 7.820e+02 7.820e+02    0.000  0.98864    
design_construct:treatment:before_after  3 7.087e+06 2.362e+06    0.620  0.60610    
Residuals                               41 1.562e+08 3.811e+06                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(mScarlet_HSD.test <- 
    agricolae::HSD.test(mScarlet_aov, 
                        trt = c("design_construct", 
                                "treatment", 
                                "before_after"), 
                        console = TRUE))

Study: mScarlet_aov ~ c("design_construct", "treatment", "before_after")

HSD Test for FL4.Amean 

Mean Square Error:  3810672 

design_construct:treatment:before_after,  means

Alpha: 0.05 ; DF Error: 41 
Critical Value of Studentized Range: 5.154955 

Groups according to probability of means differences and alpha level( 0.05 )

Treatments with the same letter are not significantly different.
$statistics
  MSerror Df    Mean       CV
  3810672 41 19226.9 10.15293

$parameters
   test                                  name.t ntr StudentizedRange alpha
  Tukey design_construct:treatment:before_after  16         5.154955  0.05

$means
                                       FL4.Amean        std r       Min       Max       Q25       Q50
AFB2 dual-fusion:Auxin:after            2490.844  198.85812 4  2207.416  2666.530  2438.961  2544.714
AFB2 dual-fusion:Auxin:before           2026.397   46.66275 3  1973.433  2061.453  2008.869  2044.305
AFB2 dual-fusion:Control EtOH:after     2759.117  144.66745 4  2612.374  2929.881  2655.805  2747.106
AFB2 dual-fusion:Control EtOH:before    2110.115  112.55555 3  2013.715  2233.807  2048.269  2082.823
AFB2 single-fusion:Auxin:after         36197.490 5828.74906 4 31851.266 44192.014 31870.387 34373.340
AFB2 single-fusion:Auxin:before        31074.988 1904.65789 3 29016.085 32774.074 30225.445 31434.806
AFB2 single-fusion:Control EtOH:after  38385.588 1153.01803 4 36886.238 39681.451 37980.543 38487.331
AFB2 single-fusion:Control EtOH:before 31251.821  936.56398 3 30193.587 31973.960 30890.752 31587.918
TIR1 dual-fusion:Auxin:after            5753.411  381.70386 4  5202.843  6084.835  5692.279  5862.984
TIR1 dual-fusion:Auxin:before           4582.236  107.55234 3  4483.615  4696.914  4524.898  4566.180
TIR1 dual-fusion:Control EtOH:after     5556.851  452.28202 4  5075.024  6086.477  5250.871  5532.952
TIR1 dual-fusion:Control EtOH:before    4557.292  144.44763 3  4390.506  4642.111  4514.882  4639.258
TIR1 single-fusion:Auxin:after         34660.947 2185.28924 4 33220.282 37917.098 33608.882 33753.203
TIR1 single-fusion:Auxin:before        31775.292 1187.70866 3 30675.467 33034.740 31145.568 31615.670
TIR1 single-fusion:Control EtOH:after  34156.499 2380.95848 5 30640.164 37060.388 33524.915 34184.394
TIR1 single-fusion:Control EtOH:before 33266.440  288.20961 3 32971.733 33547.680 33125.820 33279.906
                                             Q75
AFB2 dual-fusion:Auxin:after            2596.597
AFB2 dual-fusion:Auxin:before           2052.879
AFB2 dual-fusion:Control EtOH:after     2850.417
AFB2 dual-fusion:Control EtOH:before    2158.315
AFB2 single-fusion:Auxin:after         38700.443
AFB2 single-fusion:Auxin:before        32104.440
AFB2 single-fusion:Control EtOH:after  38892.376
AFB2 single-fusion:Control EtOH:before 31780.939
TIR1 dual-fusion:Auxin:after            5924.116
TIR1 dual-fusion:Auxin:before           4631.547
TIR1 dual-fusion:Control EtOH:after     5838.933
TIR1 dual-fusion:Control EtOH:before    4640.685
TIR1 single-fusion:Auxin:after         34805.267
TIR1 single-fusion:Auxin:before        32325.205
TIR1 single-fusion:Control EtOH:after  35372.637
TIR1 single-fusion:Control EtOH:before 33413.793

$comparison
NULL

$groups
                                       FL4.Amean groups
AFB2 single-fusion:Control EtOH:after  38385.588      a
AFB2 single-fusion:Auxin:after         36197.490     ab
TIR1 single-fusion:Auxin:after         34660.947     ab
TIR1 single-fusion:Control EtOH:after  34156.499     ab
TIR1 single-fusion:Control EtOH:before 33266.440     ab
TIR1 single-fusion:Auxin:before        31775.292      b
AFB2 single-fusion:Control EtOH:before 31251.821      b
AFB2 single-fusion:Auxin:before        31074.988      b
TIR1 dual-fusion:Auxin:after            5753.411      c
TIR1 dual-fusion:Control EtOH:after     5556.851      c
TIR1 dual-fusion:Auxin:before           4582.236      c
TIR1 dual-fusion:Control EtOH:before    4557.292      c
AFB2 dual-fusion:Control EtOH:after     2759.117      c
AFB2 dual-fusion:Auxin:after            2490.844      c
AFB2 dual-fusion:Control EtOH:before    2110.115      c
AFB2 dual-fusion:Auxin:before           2026.397      c

attr(,"class")
[1] "group"
mScarlet_groups <- mScarlet_HSD.test$groups %>% 
  as_tibble(rownames = "names") %>%
  separate(col = names, into = c("design_construct", 
                                "treatment", 
                                "before_after"), 
           sep = "\\:", remove = FALSE) %>% 
  left_join(mScarlet_HSD.test$means %>% 
              as_tibble(rownames = "names") %>% 
              dplyr::select(c(names, Max)), 
            by = "names") %>%
  mutate(treatment = fct_rev(treatment), 
         before_after = fct_rev(before_after))
boxvenus <- 
  plate_20210619_W303_sum %>%
  dplyr::filter(time <= 0 | time >= 200) %>%
  ggplot(aes(
           x = fct_rev(before_after),
           y = FL1.Amean/1000,
         )) +
  geom_boxplot(
    aes(fill = fct_rev(treatment)), alpha = 0.7,
    outlier.shape = NA, show.legend = FALSE) + 
  geom_point(aes(color = fct_rev(treatment)),
             position = position_dodge2(width = .55), 
             size = 1) +
  geom_text(data = Venus_groups, 
            mapping = aes(y = 1.05*Max/1000, label = groups), 
             position = position_dodge2(width = 1),
            color = "black") + 
  scale_fill_manual(values = c("#8f8f8f", "#edc215")) +
  scale_color_manual(values = c("#8f8f8f", "#edc215")) +
  ylab("Venus") + 
  xlab("50 µM Auxin treatment") +  
  facet_wrap( ~ fbox, scale = "free_y") + 
  facet_grid( ~ design_construct) + 
  theme_classic() + labs(color = "") 


boxmScarlet <-
  plate_20210619_W303_sum %>%
  dplyr::filter(time <= 0 | time >= 200) %>%
  ggplot(aes(
           x = fct_rev(before_after),
           y = FL4.Amean/1000
         )) +
  geom_boxplot(aes(fill = fct_rev(treatment)), alpha = .7,
               outlier.shape = NA, show.legend = FALSE) + 
  geom_point(aes(color = fct_rev(treatment)),
             position = position_dodge2(width = .55), 
             size = 1) +
   geom_text(data = mScarlet_groups, 
            mapping = aes(y = 1.2*Max/1000, label = groups), 
             position = position_dodge2(width = 1),
            color = "black") + 
  scale_fill_manual(values = c("#8f8f8f", "#EC7063")) +
  scale_color_manual(values = c("#8f8f8f", "#EC7063")) +
  ylab("mScarlet-I") + 
  xlab("50 µM Auxin treatment") +   
  facet_wrap( ~ fbox, scale = "free_y") + 
  facet_grid( ~ design_construct, scales = "free_y") +
  theme_classic() + labs(color = "") + scale_y_log10()


guide_area() / boxvenus / boxmScarlet + 
  plot_annotation(tag_levels = "A") + 
  plot_layout(guides = "collect", heights = c(.3, 1,1)) & 
  theme(legend.box = "horizontal", 
        legend.spacing = unit(0, "pt"), 
        legend.justification = "top", 
        legend.margin = margin(), 
        legend.box.spacing = unit(0, "pt"), 
        legend.background = element_blank(), 
        legend.box.background = element_blank(), 
        legend.title = element_blank(), 
        legend.key = element_blank())

ggsave("relative-expression-box.pdf", width = 6, height = 5)
ggsave("relative-expression-box.png", width = 6, height = 5)

plate_20210619_read3and12 <- read.flowSet(path = "~/Google Drive/Shared drives/PlantSynBioLab/Pat/Experiments/Time course assays/20210619/W303only_read3and12/", alter.names = TRUE) 
annotation <- createAnnotation(yourFlowSet = plate_20210619_read3and12)
write.csv(annotation,'/Users/patchaisupa/Google Drive/Shared drives/PlantSynBioLab/Pat/Experiments/Time course assays/20210619/20210619_W303only_read3and12_annotation.csv')
annotation <- read.csv('~/Google Drive/Shared drives/PlantSynBioLab/Pat/Experiments/Time course assays/20210619/20210619_W303only_read3and12_annotation.csv')
aplate_20210619_read3and12<- annotateFlowSet(yourFlowSet = plate_20210619_read3and12, annotation_df = annotation, mergeBy = 'name')
head(rownames(pData(aplate_20210619_read3and12)))
[1] "D01.fcs" "D02.fcs" "D03.fcs" "D04.fcs" "D07.fcs" "D08.fcs"
head(pData(aplate_20210619_read3and12))
NA
W303_read3and12 <- summarizeFlow(aplate_20210619_read3and12,  gated = TRUE)
[1] "Summarizing all events..."
W303_read3and12 <- W303_read3and12 %>% 
  mutate(design = str_extract(design_construct, "(?<=\\s).*")) %>%
  mutate(design = str_extract(design_construct, ".*(?=\\s)")) 

venus3and12_unnorm <- 
  ggplot(W303_read3and12, 
         aes(x=design_construct, 
             y=FL1.Amean, 
             alpha = fct_rev(before_after), 
             group=treatment)) +
  geom_point(aes(colour = factor(treatment), 
                 shape = factor(treatment)), size = 2,
             position = position_jitterdodge(
               dodge.width = 0.7, 
               jitter.width = 0.5)) + 
  scale_color_manual(values=c("#F1C40F", "#5F6A6A")) +
  ylab("Venus") + theme_classic() +
  theme(axis.text.x = element_text(angle=45, hjust = 1)) + 
  scale_alpha_manual(values = c(0.3, 0.8))

mScarlet3and12_unnorm  <- 
  ggplot(W303_read3and12, 
         aes(x=design_construct, 
             y=FL4.Amean, 
             alpha = fct_rev(before_after), 
             group=treatment)) +
  geom_point(aes(colour = factor(treatment), 
                 shape = factor(treatment)), 
             size = 2, 
             position = position_jitterdodge(
               dodge.width = .7, 
               jitter.width =.5)) + 
  scale_color_manual(values=c("#E74C3C", "#5F6A6A")) +
  ylab("mScarlet-I") + theme_classic() + 
  theme(axis.text.x = element_text(angle=45, hjust = 1)) + 
  scale_alpha_manual(values = c(0.3, 0.8))

guide_area() / (venus3and12_unnorm | mScarlet3and12_unnorm) + 
  plot_layout(guides = "collect", 
              heights = c(1, 3))  +
  plot_annotation(tag_levels = "A") &
  theme(legend.position='top', legend.direction = "vertical",
        legend.title = element_blank(), 
        axis.title.x = element_blank(), 
        legend.justification = "left", 
        legend.box.just = "left", 
        legend.margin = margin())
ggsave("relative-expression.png", width = 4, height = 3)
ggsave("relative-expression.pdf", width = 4, height = 3)

Coefficient of variation (CV) analysis


data <- steadyState(aplate_20210619_W303, gated = TRUE)
[1] "No further gating applied."
[1] "Converting events..."
#data <- tidyFlow(aplate_20210619_W303)

data <- subset(data, strain == "yWL161" & name %in% c("11L01.fcs", "11L07.fcs"))

#range(data$FL1.A)
#sd(data$FLratio)/mean(data$FLratio)
#range(data$FLratio)
data <- subset(data, FL1.A >1 & FL4.A > 1)
data$FLratio <- data$FL1.A/data$FL4.A
range(data$FL1.A)
[1]     722 2579491
#calculate cvs
sd(data$FLratio)/mean(data$FLratio)
[1] 1.821223
range(data$FLratio)
[1]   0.06052985 488.44186047
cv <- function(x) return(round(sd(x)/mean(x),2))

#calculate normalized values
data$Venus <- data$FL1.A / median(data$FL1.A)
data$mScarlet <- data$FL4.A / median(data$FL4.A)
data$ratio <- data$FLratio / median(data$FLratio)
CVs <- data %>% group_by(treatment) %>%
  summarise(across(where(is_double), cv))
# make a tidy, long dataset 

data_long <- data %>% 
  dplyr::select(treatment, Venus, mScarlet, ratio) %>%
  pivot_longer(cols = c(Venus, mScarlet, ratio), 
               names_to = "parameter", 
               values_to = "value") 
# need to also format CVs appropriately for annotating
CVs <- CVs %>% dplyr::select(treatment, Venus, mScarlet, ratio) %>%
    pivot_longer(cols = c(Venus, mScarlet, ratio), 
               names_to = "parameter", 
               values_to = "value")

#data
CV_plot <- ggplot(data = data_long, 
       mapping = aes(x = value, 
                     color = treatment)) + 
  geom_density() + xlim(c(-1,4)) + 
  labs(x = "median normalized intensity", color = "treatment") + 
  facet_grid(parameter~.) + theme_test() + 
  geom_text(data = subset(CVs, treatment == "Auxin"), 
             aes(label = paste0("CV = ", value)),
             x = 0.1, y = 0.6) + 
  geom_text(data = subset(CVs, treatment == "Control EtOH"), 
             aes(label = paste0("CV = ", value)), 
            x = 1.8, y = 0.6) + 
  scale_color_viridis_d(option = "D", end = .75, direction = -1)
CV_plot

Auxin prodcution in stationary phase

Read in annotated flowSet

flowSet <- read.flowSet(path = paste0("~/Google Drive/Shared drives/PlantSynBioLab/Auxin Biosensor Manuscript/Auxin Biosensor Data/FlowSets/", experiment_date, "_", experiment_name), phenoData = "annotation.txt")
write.flowSet(flowSet, "flowSets/auxin-biosynthesis")
flowSet <- read.flowSet(path = "flowSets/auxin-biosynthesis/", phenoData = "annotation.txt")

Summary Analysis

load("PSB_Accuri_W303.RData")
dat_sum <- summarizeFlow(flowSet, ploidy = "haploid", only = "yeast") # These gates might not work well for YPH499, but there was a lot of debris
[1] "Gating with haploid yeast gate..."
[1] "Summarizing all yeast events..."
dat_sum <- mutate(.data = dat_sum, across(starts_with("FL"), as.numeric)) %>%
  mutate(strain = str_remove(strain, " ratiometric sensor") %>% 
           str_replace(pattern = "in trans", 
                       replacement = "single-fusion") %>%
           str_replace(pattern = "in cis",
                       replacement = "dual-fusion"))
dat_sum$pred_auxin <- dat_sum$FL4.Amean/dat_sum$FL1.Amean 
dat_sum$pred_auxin_SE <- with(dat_sum, 
                              sqrt((FL4.Asd/100/FL4.Amean)^2 +
                              (FL1.Asd/100/FL1.Amean)^2)*pred_auxin)
dat_sum$pred_auxin_sd <- with(dat_sum, 
                              sqrt((FL4.Asd/FL4.Amean)^2 + 
                              (FL1.Asd/FL1.Amean)^2)*pred_auxin)
ggplot(data = dat_sum, 
       aes(x = fct_reorder(treat, pred_auxin), y = pred_auxin,
           color = factor(strain))) +
  geom_point() + 
  theme(axis.text.x = element_text(angle = 45, 
                                   hjust = 1, vjust = 1)) + 
  facet_grid(.~strain, scales = "free_x") + coord_flip() +
  theme(legend.position = "bottom", 
        legend.direction = "vertical") + 
  labs(x = "", y = "Predicted auxin (mScarlet-I/Venus-IAA17)", 
       color = "strain")
ggsave("strain_sensor_comparison_raw.pdf", width = 8, height = 3)

dat_sum <- dat_sum %>% group_by(strain) %>% 
  mutate(norm_pred_auxin = 
           pred_auxin / mean(pred_auxin
                             [which(.data$treat == 
                            "aerobic exponential phase")]))

ggplot(data = dat_sum, aes(x = fct_reorder(treat, norm_pred_auxin),
                           y = norm_pred_auxin,
                           color = factor(strain))) +
  geom_point(position = position_jitter(width = 0.2)) + 
  theme(axis.text.x = element_text(angle = 45, 
                                   hjust = 1, vjust = 1)) + 
  coord_flip() + theme(legend.position = "top", 
                       legend.direction = "vertical") + 
  labs(x = "", 
       y = "Normalized Predicted auxin (mScarlet-I/Venus-IAA17)", 
       color = "strain")
ggsave("strain_sensor_comparison_norm.pdf", width = 5, height = 5)

Full distributions

data <- steadyState(flowset = flowSet, ploidy = "haploid", only = "yeast")
[1] "Gating with haploid yeast gate..."
[1] "Converting events..."
hist(x = log(data$FL1.A, 10))

hist(x = log(data$FL4.A, 10))

data$pred_auxin <- data$FL4.A/data$FL1.A
data <- data %>% dplyr::filter(FL1.A > 1 & FL4.A > 1)
data$treat <- data$treat %>% str_remove("phase")
endog_auxin <- ggplot(
  data = subset(
    data,
    strain == "W303 ratiometric sensor AFB2 in cis" &
      pred_auxin < 2),
  aes(
    x = pred_auxin,
    y = fct_reorder(treat, .x = pred_auxin, 
                    .fun = median, .desc = TRUE) %>% 
      fct_relevel("aerobic exponential ", after = Inf),
    fill = factor(stat(quantile))
  )
) +
  stat_density_ridges(
    geom = "density_ridges_gradient",
    calc_ecdf = TRUE,
    quantiles = 4,
    color = "grey",
    alpha = 0.5
  ) +
  scale_fill_viridis_d(name = "Quartiles") +
  theme(legend.position = NULL) +
  #facet_wrap(.~treat) +
  xlim(c(-0.1, 1)) +
  labs(y = NULL, x = "Predicted relative auxin production (AU) \n (AFB2-mScarlet-I/Venus-IAA17)") + theme_ridges() + theme(legend.position = "none")
ggsave("20210626_auxin_production_quartiles.pdf", width = 5, height = 4)
endog_auxin

Biosensor sensitivity at stationary phase

plate_09282022 <- read.plateSet(path = "~/Google Drive/Shared drives/PlantSynBioLab/Pat/Experiments/Does-response assay/09282022_yWL210_DRA-stationary/Data/", pattern = "S-DRA*") 
annotation_09282022 <- read.csv('~/Google Drive/Shared drives/PlantSynBioLab/Pat/Experiments/Does-response assay/09282022_yWL210_DRA-stationary/09282022_stationaryphase_annotation.csv')

aplate_09282022 <- annotateFlowSet(yourFlowSet = plate_09282022, annotation_df = annotation_09282022, mergeBy = 'name')
head(rownames(pData(aplate_09282022)))
head(pData(aplate_09282022))
write.flowSet(aplate_09282022, "flowSets/AFB2-dual-stationary")
aplate_09282022 <- read.flowSet(path = "flowSets/AFB2-dual-stationary/", phenoData = "annotation.txt")

dat_sumGr_09282022 <- summarizeFlow(aplate_09282022, gated = TRUE)
[1] "Summarizing all events..."
model.LL4_09282022<- drm(YL1.Amean/BL1.Amean~dose, data=subset(dat_sumGr_09282022, set == "4"), fct=LL.4(names = c("Slope", "Lower Limit", "Upper Limit", "ED50")))

pm210stat <- expand.grid(treatment=exp(seq(log(1e-5), log(1e2), length=1000))) 
pm210stat <- cbind(pm210stat,predict(model.LL4_09282022, newdata=pm210stat, interval="confidence"))  #m2all = model of 210 data

plot210_stat <- ggplot(subset(dat_sumGr_09282022, set == "4"), 
                       aes(x = dose, y = YL1.Amean/BL1.Amean))  +
 geom_ribbon(data = pm210stat, 
             aes(x = treatment, y = Prediction, 
                 ymin = Lower, ymax=Upper), alpha = .2) +
  geom_line(data = pm210stat, aes(x = treatment, y = Prediction)) + 
  ylab("AFB2-mScarlet-I/Venus-IAA17") + 
  xlab("Exogenous Auxin (µM)") + 
  scale_x_log10(labels = 
                  scales::label_number(drop0trailing = TRUE)) + 
  scale_color_viridis_d() + geom_point() + 
  theme_classic(base_size = 14) + 
  theme(legend.position = "none") 
plot210_stat

Combined figure

endog_auxin + plot210_stat + plot_annotation(tag_levels = "A")

ggsave("auxin-accumulation.pdf", width = 8, height = 4)
ggsave("auxin-accumulation.png", width = 8, height = 4)

Mutant library analysis

Here we aim to test auxin induced Venus-IAA17 degradation relative to the bicistronic mScarlet-I control with AFB2 expressed from the p1 plasmid in the OrthoRep continuous mutagenesis system.

Procedure

Temperature 30 degree celcius Shaking at 250rpm DO-URA-HIS, starting volume: 10 mL Overnight concentration: 30 events/uL 1PM started from 2 colonies

Initial reading ~10AM Auxin concentration: 100 uM (.1% DMSO) After 4th reading: B04.fcs

###Importing and annotating data

aplate1 <- read.flowSet(path = 'flowSets/OrthoRep', phenoData = "annotation.txt")
dat_sum <- summarizeFlow(aplate1, gated = TRUE)
[1] "Summarizing all events..."
data <- flowTime::tidyFlow(aplate1, gated = TRUE)
[1] "No further gating applied."
[1] "Converting events..."
data <- subset(data, FL4.A > 1)
range(data$FL1.A)
[1]        0 15867629
range(data$FL4.A)
[1]       6 7690137
data$ratio <- data$FL1.A / data$FL4.A
data <- subset(data, data$ratio < 10)

Make a kernel density plot overlapping mutant population with parent, DMSO and IAA that we can then stack a few timepoints with facets. For timepoints it looks like the 2nd, 7th and 12th would be a good demonstration of the timecourse.

wells <- dat_sum %>%
                 # Get well/file names of the 2nd, 7th and 12th readings of the 4 strains. 
                 dplyr::slice(1:4 + unlist(lapply((c(2, 7, 12) - 1)*4, rep, 4))) %>%
                 dplyr::pull("name")
data <- 
  dplyr::filter(data, name %in% wells)

data$approxtime <- signif(data$etime, digits = 1)
signif(unique(data$approxtime), 1)
[1]  30 200 600
data$approxtime <- as.factor(data$approxtime) %>% fct_recode("0 hour" = "30", "1 hour" = "200", "6 hour" = "600")
data$strain <- fct_recode(data$strain, "high fidelity" = "wild" , "error prone" = "mutant")
data <- 
  data %>% 
  mutate(Venus = FL1.A, 
         mScarlet = FL4.A, 
         ratio = Venus/mScarlet)

cv <- function(x) return(round(sd(x)/mean(x),2))
CVs <- data %>% group_by(treatment, strain) %>% dplyr::summarise(across(where(is_double), cv))
CVs <- CVs %>% dplyr::select(treatment, Venus, mScarlet, ratio) %>%
    pivot_longer(cols = c(Venus, mScarlet, ratio), 
               names_to = "parameter", 
               values_to = "value")

kernel_plot <- ggplot(data = data, 
       mapping = aes(x = ratio, 
                     color = treatment, linetype = strain)) + 
  geom_density() + coord_cartesian(x = c(0.5,2)) + 
  facet_grid(approxtime~.) + theme_test() + 
  scale_color_viridis_d(option = "D", end = .75, direction = -1) + 
  labs(x = "Venus-IAA17/mScarlet ratio", linetype = "polymerase")
kernel_plot
ggsave("orthorep_degradation.pdf", height = 4, width = 4)
ggsave("orthorep_degradation.png", height = 4, width = 4)

Gating Strategy

data <- aplate1[wells]

To gate out the high FSC-A debris we will use only the lower 99.5% of the data

g <- gate_quantile(fr = data[[1]], channel = "FSC.A", probs = 0.995)
autoplot(data[[1]], x = "FSC-A") + geom_gate(g)

Subset(data[[1]], !g)
flowFrame object 'A05.fcs'
with 9950 cells and 14 observables:
       name   desc     range  minRange  maxRange
$P1   FSC.A  FSC-A  16777216         0  16777216
$P2   SSC.A  SSC-A  16777216         0  16777216
$P3   FL1.A  FL1-A  16777216         0  16777216
$P4   FL2.A  FL2-A  16777216         0  16777216
$P5   FL3.A  FL3-A  16777216         0  16777216
...     ...    ...       ...       ...       ...
$P10  FL2.H  FL2-H  16777216         0  16777216
$P11  FL3.H  FL3-H  16777216         0  16777216
$P12  FL4.H  FL4-H  16777216         0  16777216
$P13  Width  Width  16777216         0  16777216
$P14   Time   Time  16777216         0  16777216
161 keywords are stored in the 'description' slot
autoplot(Subset(data[[3]], !g), x = "FSC-A", "SSC-A")

autoplot(data[[3]], "FSC-A", "SSC-A") + geom_gate(g)

Now we need to gate out only singlet cells

chnl <- c("FSC-A", "FSC-H")
singlets <- gate_singlet(x = Subset(data[[1]], !g), area = "FSC.A",height = "FSC.H", prediction_level = 0.999, maxit = 20)
autoplot(data[[1]], "FSC-A", "FSC-H") + geom_gate(singlets)

Now we can assess this singlets gate over for several frames

length(data)
[1] 12
autoplot(data, x = "FSC-A", y = "FSC-H") + geom_gate(singlets) + facet_wrap("name", ncol = 4) 


autoplot(Subset(data, !g) %>% Subset(singlets), x = "FL1-A") + facet_wrap("name", ncol = 4) 

autoplot(Subset(data, !g |singlets), x = "FSC-A", y = "SSC-A") + facet_wrap("name", ncol = 4)

This looks very consistent across the course of this experiment. We can summarize this gating across the whole experiment, but will not show this here.

#summary(filter(data, !g & singlets))
data <- Subset(data, !g & singlets)

Plot Fluorescence vs. Time

dat_sum <- summarizeFlow(data, gated = TRUE)
[1] "Summarizing all events..."
ggplot(data = dat_sum, aes(x = time, y = FL1.Amean/FL4.Amean, color = factor(strain), linetype = factor(treatment)))+
geom_line() + xlab("Time post first reading (min)") +
ylab("Reporter Fluorescence, FL1 (AU)") + geom_text(aes(label = name))


ggplot(data = dat_sum, aes(x = time, y = conc, color = factor(strain), linetype = factor(treatment)))+
geom_line() + xlab("Time post first reading (min)") +
ylab("Reporter Fluorescence, FL1 (AU)")

Define a gate containing ~95% of the untreated cells expressing the wildtype polymerase.

logt <- estimateLogicle(data[["E05.fcs"]], channels = c("FL4.A", "FL1.A"))
data <- transform(data[c("E05.fcs", "E06.fcs", "E07.fcs", "E08.fcs")], logt)
untreated <- gate_flowclust_2d(data[["E05.fcs"]], xChannel = "FL4.A", yChannel = "FL1.A", K = 1, quantile = 0.90, filterId = "untreated")
treated <- gate_flowclust_2d(data[["E06.fcs"]], xChannel = "FL4.A", yChannel = "FL1.A", K = 1, quantile = 0.90, filterId = "treated")



ggcyto(data, aes(x = "FL4.A", y = "FL1.A")) + 
  geom_point(color = "green4", alpha = 0.1, size = 0.5) + 
  ggthemes::theme_base() + 
  labs(x = "mScarlet-I (free FP)", y = "Venus-IAA17") +
  facet_grid(fct_rev(strain) %>% 
               fct_recode("wild-type" = "wild")~treatment) + 
  coord_cartesian(xlim = c(1.4,2.6), ylim = c(1.4,2.6)) + 
  geom_gate(untreated, colour = "magenta", linetype = 2) + 
  geom_gate(treated, colour = "magenta") +
  geom_stats(adjust = c(0.1, 0.05), size = 4.5, alpha = 0.5) 


ggsave("sorting-strategy.pdf", height = 4.5, width = 6)
ggsave("sorting-strategy.png", height = 4.5, width = 6)

Mutation frequency calculation

As an overestimate, these cells were cultured for ~12 generations over 24 hours. So this results in 212 cells for each initial.

AFB2 is 1725 bps, and the mutation rate of the error prone polymerase is calculated to be \(1 \times 10^{-5}\) substitutions per base. We will assume there is only 1 copy of the p1 plasmid per cell. We will also assume withing this coding sequence, for every 2.1 substitutions (sub) there is 1 nonsynonymous substitution (nsub), per the average across the codon table, not factoring in codon usage across TIR1.

\[ \begin{array}{c|c|c} 1 \times 10^{-5} \text{ sub} & 1725 \text{ bases} * 2 \text{ (bp)} & 1 \text{ nsub} \\ \hline \text{base} & \text{cell} & 2.1 \text{ sub} \end{array} = 0.02 \frac{\text{nsub}}{\text{cell}} \] So on the low end, ~0.0164286 percent of cells have a nonsynonymous substitution in TIR1. But because this substitution rate is really compounding over 12 generations, this estimate is quite low.

Based on this baseline rate per cell (or generation, cell duplication) \(r\), we can then compound this over \(t\) generations, to find the compounded rate \(r_c\). \[ r_c = (1 + r)^t-1 = (1+0.0164286)^{12}-1 = 0.2159686 \] And on the high end, which is a more accurate measure, ~22% of our population contains a nonsynonymous substitution in TIR1.

Session Info

sessionInfo()
R Under development (unstable) (2022-10-30 r83209)
Platform: aarch64-apple-darwin20 (64-bit)
Running under: macOS Ventura 13.2.1

Matrix products: default
LAPACK: /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRlapack.dylib

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] agricolae_1.3-5      ggthemes_4.2.4       patchwork_1.1.2      wesanderson_0.3.6    flowClust_3.37.0    
 [6] flowStats_4.11.0     ggcyto_1.27.4        flowWorkspace_4.11.0 ncdfFlow_2.45.0      BH_1.78.0-0         
[11] openCyto_2.11.1      gridExtra_2.3        drc_3.0-1            MASS_7.3-58.1        lubridate_1.9.2     
[16] forcats_1.0.0        purrr_1.0.1          readr_2.1.4          tibble_3.1.8         tidyverse_2.0.0     
[21] tidyr_1.3.0          dplyr_1.1.0          ggridges_0.5.4       stringr_1.5.0        ggplot2_3.4.1       
[26] flowTime_1.23.1      flowCore_2.11.0     

loaded via a namespace (and not attached):
  [1] RColorBrewer_1.1-3  rstudioapi_0.14     magrittr_2.0.3      TH.data_1.1-1       rainbow_3.7        
  [6] farver_2.1.1        ragg_1.2.5          zlibbioc_1.45.0     vctrs_0.5.2         RCurl_1.98-1.9     
 [11] htmltools_0.5.4     plotrix_3.8-2       haven_2.5.2         deSolve_1.34        hdrcde_3.4         
 [16] pracma_2.4.2        KernSmooth_2.23-20  plyr_1.8.8          sandwich_3.0-2      zoo_1.8-11         
 [21] mime_0.12           lifecycle_1.0.3     pkgconfig_2.0.3     Matrix_1.5-3        R6_2.5.1           
 [26] fastmap_1.1.0       shiny_1.7.4         digest_0.6.31       klaR_1.7-1          colorspace_2.0-3   
 [31] S4Vectors_0.37.3    textshaping_0.3.6   labeling_0.4.2      cytolib_2.11.0      fansi_1.0.3        
 [36] timechange_0.2.0    abind_1.4-5         compiler_4.3.0      withr_2.5.0         carData_3.0-5      
 [41] DBI_1.1.3           hexbin_1.28.2       highr_0.9           corpcor_1.6.10      gtools_3.9.4       
 [46] tools_4.3.0         rrcov_1.7-2         httpuv_1.6.9        glue_1.6.2          IDPmisc_1.1.20     
 [51] questionr_0.7.8     nlme_3.1-161        promises_1.2.0.1    grid_4.3.0          cluster_2.1.4      
 [56] generics_0.1.3      gtable_0.3.1        fda_6.0.5           labelled_2.10.0     tzdb_0.3.0         
 [61] data.table_1.14.6   hms_1.1.2           car_3.1-1           utf8_1.2.2          BiocGenerics_0.45.0
 [66] pillar_1.8.1        later_1.3.0         robustbase_0.95-0   splines_4.3.0       lattice_0.20-45    
 [71] AlgDesign_1.2.1     survival_3.4-0      deldir_1.0-6        ks_1.14.0           RProtoBufLib_2.11.0
 [76] tidyselect_1.2.0    RBGL_1.75.0         fds_1.8             miniUI_0.1.1.1      knitr_1.41         
 [81] stats4_4.3.0        xfun_0.35           Biobase_2.59.0      matrixStats_0.63.0  DEoptimR_1.0-11    
 [86] stringi_1.7.8       codetools_0.2-18    interp_1.1-3        Rgraphviz_2.43.0    graph_1.77.1       
 [91] cli_3.6.0           flowViz_1.63.0      systemfonts_1.0.4   xtable_1.8-4        munsell_0.5.0      
 [96] Rcpp_1.0.9          png_0.1-8           XML_3.99-0.13       parallel_4.3.0      ellipsis_0.3.2     
[101] mclust_6.0.0        latticeExtra_0.6-30 jpeg_0.1-10         bitops_1.0-7        viridisLite_0.4.1  
[106] mvtnorm_1.1-3       scales_1.2.1        crayon_1.5.2        pcaPP_2.0-3         combinat_0.0-8     
[111] rlang_1.0.6         multcomp_1.4-22     mnormt_2.1.1       

  1. Biological Systems Engineering, Virginia Tech, Blacksburg, VA , USA, co-first author↩︎

  2. Biological Systems Engineering, Virginia Tech, Blacksburg, VA, USA, co-first author↩︎

  3. Fralin Life Sciences Institute, Virginia Tech, Blacksburg, VA, USA↩︎

  4. Biological Systems Engineering, Virginia Tech, Blacksburg, VA, USA↩︎

  5. Biological Systems Engineering, Virginia Tech, Blacksburg, VA, USA↩︎

  6. Biochemistry and Fralin Life Sciences Institute, Virginia Tech, Blacksburg, VA, USA↩︎

  7. Biological Systems Engineering, Fralin Life Sciences Institute, and Translational Plant Sciences Center, Virginia Tech, Blacksburg, VA, USA, ↩︎

LS0tCnRpdGxlOiAiU3VwcGxtZW50YWwgcmVwcm9kdWNpYmxlIGFuYWx5c2lzIGZvcjogR2VuZXRpY2FsbHkgZW5jb2RlZCwgbm9pc2UtdG9sZXJhbnQsCiAgYXV4aW4gYmlvc2Vuc29ycyBpbiB5ZWFzdCBmYWNpbGl0YXRlIG1ldGFib2xpYyBlbmdpbmVlcmluZyBhbmQgZGlyZWN0ZWQgZXZvbHV0aW9uIgphdXRob3I6Ci0gIlBhdGFyYXN1ZGEgQ2hhaXN1cGFeW0Jpb2xvZ2ljYWwgU3lzdGVtcyBFbmdpbmVlcmluZywgVmlyZ2luaWEgVGVjaCwgQmxhY2tzYnVyZywKICBWQSAsIFVTQSwgY28tZmlyc3QgYXV0aG9yXSIKLSAiTWFoYnVidXIgUmFobWFuKl5bQmlvbG9naWNhbCBTeXN0ZW1zIEVuZ2luZWVyaW5nLCBWaXJnaW5pYSBUZWNoLCBCbGFja3NidXJnLCBWQSwKICBVU0EsIGNvLWZpcnN0IGF1dGhvcl0iCi0gU2hlcnJ5IEIuIEhpbGRyZXRoXltGcmFsaW4gTGlmZSBTY2llbmNlcyBJbnN0aXR1dGUsIFZpcmdpbmlhIFRlY2gsIEJsYWNrc2J1cmcsIFZBLAogIFVTQV0KLSBTYWVkZSBNb3NlbGV5XltCaW9sb2dpY2FsIFN5c3RlbXMgRW5naW5lZXJpbmcsIFZpcmdpbmlhIFRlY2gsIEJsYWNrc2J1cmcsIFZBLCBVU0FdCi0gQ2hhdW5jZXkgR2F0bGluZ15bQmlvbG9naWNhbCBTeXN0ZW1zIEVuZ2luZWVyaW5nLCBWaXJnaW5pYSBUZWNoLCBCbGFja3NidXJnLCBWQSwKICBVU0FdCi0gUmljaGFyZCBGLiBIZWxtXltCaW9jaGVtaXN0cnkgYW5kIEZyYWxpbiBMaWZlIFNjaWVuY2VzIEluc3RpdHV0ZSwgVmlyZ2luaWEgVGVjaCwKICBCbGFja3NidXJnLCBWQSwgVVNBXQotIFIuIENsYXkgV3JpZ2h0XltCaW9sb2dpY2FsIFN5c3RlbXMgRW5naW5lZXJpbmcsIEZyYWxpbiBMaWZlIFNjaWVuY2VzIEluc3RpdHV0ZSwKICBhbmQgVHJhbnNsYXRpb25hbCBQbGFudCBTY2llbmNlcyBDZW50ZXIsIFZpcmdpbmlhIFRlY2gsIEJsYWNrc2J1cmcsIFZBLCBVU0EsIHdyaWdodHJjQHZ0LmVkdV0Kb3V0cHV0OgogIHdvcmRfZG9jdW1lbnQ6IGRlZmF1bHQKICBodG1sX2RvY3VtZW50OgogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0CiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdAotLS0KCmBgYHtyIHNldHVwLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIGNvbGxhcHNlID0gVFJVRSwgCiAgICAgICAgICAgICAgICAgICAgICB0aWR5ID0gVFJVRSwgbWVzc2FnZSA9IEZBTFNFLCAKICAgICAgICAgICAgICAgICAgICAgIHdhcm5pbmcgPSBGQUxTRSkKbGlicmFyeShmbG93Q29yZSkKbGlicmFyeShmbG93VGltZSkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHN0cmluZ3IpICAgICAgICAgICAgICAgICAgICAgICAgCmxpYnJhcnkoZ2dyaWRnZXMpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkodGlkeXIpCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGRyYykKbGlicmFyeShncmlkRXh0cmEpCmxpYnJhcnkob3BlbkN5dG8pCmxpYnJhcnkoZ2djeXRvKQpsaWJyYXJ5KGZsb3dTdGF0cykKbGlicmFyeShmbG93Q2x1c3QpCmxpYnJhcnkod2VzYW5kZXJzb24pCmxpYnJhcnkocGF0Y2h3b3JrKQpsaWJyYXJ5KGdndGhlbWVzKQpsaWJyYXJ5KGFncmljb2xhZSkKYGBgCgojIFRpbWUtY291cnNlIHJlc3BvbnNlIGFuZCByYXRpb21ldHJpYyBtZWFzdXJlbWVudCBvZiB0aGUgc2luZ2xlLWZ1c2lvbiBiaW9zZW5zb3JzCgojIyBUaW1lLWNvdXJzZSBkZWdyYWRhdGlvbgoKYGBge3IsIGV2YWw9RkFMU0V9CiMgUmVhZCBpbiBmbG93IHNldHMgZnJvbSAyMDIwMDYxMSBhbmQgMjAyMDA2MTQKZmxvd1NldCA8LSByZWFkLnBsYXRlU2V0KHBhdGggPSAifi9Hb29nbGUgRHJpdmUvU2hhcmVkIGRyaXZlcy9QbGFudFN5bkJpb0xhYi9EYXRhL01haGJ1Yi9GbG93U2V0cy8iLCBwYXR0ZXJuID0gIjIwMjAwNiIsIHBoZW5vRGF0YSA9ICJhbm5vdGF0aW9uLnR4dCIpCmZsb3dTZXQgPC0gZmxvd1NldFt3aGljaChmbG93U2V0QHBoZW5vRGF0YUBkYXRhJHN0cmFpbiAlaW4lIGMoIlQxVDEiLCAiQTJBMiIpKV0KCndyaXRlLmZsb3dTZXQoZmxvd1NldCwgImZsb3dTZXRzL3NpbmdsZS10aW1lLWNvdXJzZSIpCgpgYGAKCgpgYGB7cn0KZmxvd1NldCA8LSByZWFkLmZsb3dTZXQocGF0aCA9ICAiZmxvd1NldHMvc2luZ2xlLXRpbWUtY291cnNlIiwgcGhlbm9EYXRhID0gImFubm90YXRpb24udHh0IikKIyBsb2FkIGdhdGVzIGZvciB0aGlzIHN0cmFpbi9jeXRvbWV0ZXIKbG9hZCgiUFNCX0FjY3VyaV9XMzAzLlJEYXRhIikKZGF0YV9zdW0gPC0gc3VtbWFyaXplRmxvdyhmbG93c2V0ID0gZmxvd1NldCwgcGxvaWR5ID0gImRpcGxvaWQiLCBvbmx5ID0gInNpbmdsZXRzIikKdGltZTBfMTQgPC0gZGF0YV9zdW0gJT4lIGRwbHlyOjpmaWx0ZXIobmFtZSA9PSAiMjFEMTAuZmNzIikgJT4lIAogIHB1bGwoYnRpbWUpIAp0aW1lMF8xMSA8LSBkYXRhX3N1bSAlPiUgZHBseXI6OmZpbHRlcihuYW1lID09ICIxMUcwMi5mY3MiKSAlPiUgCiAgcHVsbChidGltZSkgCmRhdGFfc3VtIDwtIAogIGRhdGFfc3VtICU+JSAKICAgIG11dGF0ZSh0aW1lID0gY2FzZV93aGVuKAogICAgICBmb2xkZXIgPT0gIjIwMjAwNjExX0FGQl9lcGlzdGFzaXMiIH4gCiAgICAgICAgLiRidGltZSAtIHRpbWUwXzExLCAKICAgICAgZm9sZGVyID09ICIyMDIwMDYxNF9BRkJfZXBpc3Rhc2lzIiB+CiAgICAgICAgLiRidGltZSAtIHRpbWUwXzE0CiAgICApKQpgYGAKCmBgYHtyfQpzaGFwZXMgPC0gYygiRE1TTyIgPSAxLCAiSUFBIiA9IDE2KQpsaW5lcyA8LSBjKCJETVNPIiA9IDIsICJJQUEiID0gMSkKCmRhdGFfc3VtJHJhdGlvIDwtIGRhdGFfc3VtJEZMMS5BbWVhbi9kYXRhX3N1bSRGTDQuQW1lYW4KZGF0YV9zdW0kVmVudXMgPC0gZGF0YV9zdW0kRkwxLkFtZWFuLzEwMDAwCmRhdGFfc3VtX2xvbmcgPC0gZGF0YV9zdW0gJT4lIAogIGRwbHlyOjpzZWxlY3QodGltZSwgdHJlYXRtZW50LCB5V0wsIGZvbGRlciwgc3RyYWluLCByYXRpbywgVmVudXMpICU+JQogIHBpdm90X2xvbmdlcihjb2xzID0gYyhyYXRpbywgVmVudXMpLCBuYW1lc190byA9ICJwYXJhbWV0ZXIiKQpkZWdfcGxvdCA8LSBnZ3Bsb3QoZGF0YSA9IHN1YnNldChkYXRhX3N1bV9sb25nLCB5V0wgPT0gIjE2NiIpLCAKICAgICAgIGFlcyh4ID0gdGltZSwgeSA9IHZhbHVlLCBzaGFwZSA9IHRyZWF0bWVudCwgCiAgICAgICAgICAgY29sb3IgPSB0cmVhdG1lbnQsIAogICAgICAgICAgIGdyb3VwID0gaW50ZXJhY3Rpb24odHJlYXRtZW50LCBmb2xkZXIpKSkgKyAKICBnZW9tX3BvaW50KCkgKyBsYWJzKHkgPSAiaW50ZW5zaXR5IChBVSkiLCB4ID0gInRpbWUgcG9zdCBhdXhpbiBhZGRpdGlvbiAobWluKSIpICsKICBmYWNldF93cmFwKH5mY3RfcmV2KHBhcmFtZXRlciksIHNjYWxlcyA9ICJmcmVlIikgKyAKICBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gc2hhcGVzKSArIAogIGdlb21fbGluZShhZXMobGluZXR5cGUgPSB0cmVhdG1lbnQpKSArCiAgc2NhbGVfbGluZXR5cGVfbWFudWFsKHZhbHVlcyA9IGxpbmVzKSArIAogIHNjYWxlX2NvbG9yX3ZpcmlkaXNfZChvcHRpb24gPSAiRCIsIGVuZCA9IDAuNzUsIGRpcmVjdGlvbiA9IC0xKSArIAogIHRoZW1lX3Rlc3QoKQpkZWdfcGxvdApgYGAKCmBgYHtyfQpkYXRhIDwtIGZsb3dUaW1lOjp0aWR5RmxvdyhmbG93U2V0LCBwbG9pZHkgPSAiZGlwbG9pZCIsIG9ubHkgPSAic2luZ2xldHMiKQpgYGAKCmBgYHtyfQojIGdldCBsYXRlIHRpbWUgcG9pbnRzIGZvciBvbmUgc3RyYWluCmxhc3RfcmVhZGluZyA8LSAKICB0YWlsKHVuaXF1ZShkYXRhW3doaWNoKGRhdGEkeVdMID09IDE2NiksICJuYW1lIl0pLDQpICU+JSBoZWFkKDIpCmRhdGEgPC0gZHBseXI6OmZpbHRlcihkYXRhLCB5V0wgPT0gIjE2NiIgJiBuYW1lICVpbiUgbGFzdF9yZWFkaW5nKQojIGNsZWFuIHRoaXMgdXAsIGN1dCBvZmYgemVyb3MKZGF0YSA8LSBzdWJzZXQoZGF0YSwgRkwxLkEgPjEgJiBGTDQuQSA+IDEpCmRhdGEkRkxyYXRpbyA8LSBkYXRhJEZMMS5BL2RhdGEkRkw0LkEKcmFuZ2UoZGF0YSRGTDEuQSkKI2NhbGN1bGF0ZSBjdnMKc2QoZGF0YSRGTHJhdGlvKS9tZWFuKGRhdGEkRkxyYXRpbykKcmFuZ2UoZGF0YSRGTHJhdGlvKQpgYGAKCiMjIFNpbmdsZS1mdXNpb24gQ1YgcGxvdCAKCmBgYHtyfQojY2FsY3VsYXRlIG5vcm1hbGl6ZWQgdmFsdWVzCmRhdGEkVmVudXMgPC0gZGF0YSRGTDEuQSAvIG1lZGlhbihkYXRhJEZMMS5BKQpkYXRhJG1TY2FybGV0IDwtIGRhdGEkRkw0LkEgLyBtZWRpYW4oZGF0YSRGTDQuQSkKZGF0YSRyYXRpbyA8LSBkYXRhJEZMcmF0aW8gLyBtZWRpYW4oZGF0YSRGTHJhdGlvKQojIG1ha2UgYSB0aWR5LCBsb25nIGRhdGFzZXQgCmRhdGFfbG9uZyA8LSBkYXRhICU+JSAKICBkcGx5cjo6c2VsZWN0KHRyZWF0bWVudCwgVmVudXMsIG1TY2FybGV0LCByYXRpbykgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKFZlbnVzLCBtU2NhcmxldCwgcmF0aW8pLCAKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAicGFyYW1ldGVyIiwgCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJ2YWx1ZSIpIAoKIyBuZWVkIHRvIGFsc28gZm9ybWF0IENWcyBhcHByb3JpYXRlbHkgZm9yIGFubm90YXRpbmcKY3YgPC0gZnVuY3Rpb24oeCkgcmV0dXJuKHJvdW5kKHNkKHgpL21lYW4oeCksMikpCkNWcyA8LSBkYXRhICU+JSBncm91cF9ieSh0cmVhdG1lbnQpICU+JQogIHN1bW1hcmlzZShhY3Jvc3Mod2hlcmUoaXNfZG91YmxlKSwgY3YpKQpDVnMgPC0gQ1ZzICU+JSBkcGx5cjo6c2VsZWN0KHRyZWF0bWVudCwgVmVudXMsIG1TY2FybGV0LCByYXRpbykgJT4lCiAgICBwaXZvdF9sb25nZXIoY29scyA9IGMoVmVudXMsIG1TY2FybGV0LCByYXRpbyksIAogICAgICAgICAgICAgICBuYW1lc190byA9ICJwYXJhbWV0ZXIiLCAKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gInZhbHVlIikKCkNWX3Bsb3QgPC0gZ2dwbG90KGRhdGEgPSBkYXRhX2xvbmcsIAogICAgICAgbWFwcGluZyA9IGFlcyh4ID0gdmFsdWUsIAogICAgICAgICAgICAgICAgICAgICBjb2xvciA9IHRyZWF0bWVudCkpICsgCiAgZ2VvbV9kZW5zaXR5KCkgKyBjb29yZF9jYXJ0ZXNpYW4oeCA9IGMoMCwyKSkgKyAKICBsYWJzKHggPSAibWVkaWFuIG5vcm1hbGl6ZWQgaW50ZW5zaXR5IiwgY29sb3IgPSAidHJlYXRtZW50IikgKyAKICBmYWNldF9ncmlkKGZjdF9yZWxldmVsKHBhcmFtZXRlciwgIlZlbnVzIil+LikgKyB0aGVtZV90ZXN0KCkgKyAKICBnZW9tX3RleHQoZGF0YSA9IHN1YnNldChDVnMsIHRyZWF0bWVudCA9PSAiSUFBIiksIAogICAgICAgICAgICAgYWVzKGxhYmVsID0gcGFzdGUwKCJDViA9ICIsIHZhbHVlKSksCiAgICAgICAgICAgICB4ID0gMC4zLCB5ID0gMikgKyAKICBnZW9tX3RleHQoZGF0YSA9IHN1YnNldChDVnMsIHRyZWF0bWVudCA9PSAiRE1TTyIpLCAKICAgICAgICAgICAgIGFlcyhsYWJlbCA9IHBhc3RlMCgiQ1YgPSAiLCB2YWx1ZSkpLCAKICAgICAgICAgICAgeCA9IDEuOCwgeSA9IDIpICsgCiAgc2NhbGVfY29sb3JfdmlyaWRpc19kKG9wdGlvbiA9ICJEIiwgZW5kID0gLjc1LCBkaXJlY3Rpb24gPSAtMSkKQ1ZfcGxvdApgYGAKCmBgYHtyfQpsYXlvdXQgPC0gIgpBQUFBQgpDQ0NDQwoiCkNWX3Bsb3QgICsgZ3VpZGVfYXJlYSgpICsgZGVnX3Bsb3QgKyBwbG90X2Fubm90YXRpb24odGFnX2xldmVscyA9ICJBIikgKyAKICBwbG90X2xheW91dChndWlkZXMgPSAiY29sbGVjdCIsIGhlaWdodHMgPSBjKDUsIDIpLCBkZXNpZ24gPSBsYXlvdXQpIApnZ3NhdmUoInJhdGlvLWRlZy5wZGYiLCB3aWR0aCA9IDUsIGhlaWdodCA9IDUpCmdnc2F2ZSgicmF0aW8tZGVnLnBuZyIsIHdpZHRoID0gNSwgaGVpZ2h0ID0gNSkKYGBgCgojIERvc2UtcmVzcG9uc2UgY3VydmVzIG9mIGR1YWwtZnVzaW9uIEFGQjIgYW5kIFRJUjEgYmlvc2Vuc29ycwoKIyMgQUZCMi1iYXNlZCBiaW9zZW5zb3IgKHlXTDIxMCBBRkIyIGR1YWwtZnVzaW9uLCBzaW5nbGUgcmF0aW9tZXRyaWMgY29uc3RydWN0KQoKYGBge3IsIGV2YWwgPSBGfQpwbGF0ZV9hbGxfMjEwIDwtIHJlYWQucGxhdGVTZXQocGF0aCA9ICJ+L0dvb2dsZSBEcml2ZS9TaGFyZWQgZHJpdmVzL1BsYW50U3luQmlvTGFiL1BhdC9FeHBlcmltZW50cy9Eb2VzLXJlc3BvbnNlIGFzc2F5LzExMjEyMDIyX0RSQV9vdmVybGF5ZGF0YS9Db21iaW5lIERhdGFfeVdMMjEwL0FsbCBkYXRhLyIsIHBhdHRlcm4gPSAiRFJBLSoiKSAKYGBgCgpgYGB7ciwgZXZhbCA9IEZ9Cgphbm5vdGF0aW9uIDwtIGNyZWF0ZUFubm90YXRpb24oeW91ckZsb3dTZXQgPSBwbGF0ZV9hbGxfMjEwKQp3cml0ZS5jc3YoYW5ub3RhdGlvbiwnL1VzZXJzL3BhdGNoYWlzdXBhL0dvb2dsZSBEcml2ZS9TaGFyZWQgZHJpdmVzL1BsYW50U3luQmlvTGFiL1BhdC9FeHBlcmltZW50cy9Eb2VzLXJlc3BvbnNlIGFzc2F5LzExMjEyMDIyX0RSQV9vdmVybGF5ZGF0YS9vdmVybGF5ZGF0YV9hbm5vdGF0aW9uX3lXTDIxMF9kYXRhZ2F0ZWRfZXhKYW4zMS5jc3YnKQoKYGBgCgpgYGB7ciwgZXZhbCA9IEZ9CmFubm90YXRpb24gPC0KICByZWFkLmNzdigKICAgICd+L0dvb2dsZSBEcml2ZS9TaGFyZWQgZHJpdmVzL1BsYW50U3luQmlvTGFiL1BhdC9FeHBlcmltZW50cy9Eb2VzLXJlc3BvbnNlIGFzc2F5LzExMjEyMDIyX0RSQV9vdmVybGF5ZGF0YS9vdmVybGF5ZGF0YV9hbm5vdGF0aW9uX3lXTDIxMF9kYXRhZ2F0ZWRfZXhKYW4zMS5jc3YnCiAgKQoKYXBsYXRlX2FsbF8yMTAgPC0KICBhbm5vdGF0ZUZsb3dTZXQoeW91ckZsb3dTZXQgPSBwbGF0ZV9hbGxfMjEwLAogICAgICAgICAgICAgICAgICBhbm5vdGF0aW9uX2RmID0gYW5ub3RhdGlvbiwKICAgICAgICAgICAgICAgICAgbWVyZ2VCeSA9ICduYW1lJykKaGVhZChyb3duYW1lcyhwRGF0YShhcGxhdGVfYWxsXzIxMCkpKQpoZWFkKHBEYXRhKGFwbGF0ZV9hbGxfMjEwKSkKd3JpdGUuZmxvd1NldChhcGxhdGVfYWxsXzIxMCwgCiAgICAgICAgICAgICAgb3V0ZGlyID0gImZsb3dTZXRzL0FGQjItZHVhbC15V0wyMTAtZG9zZS1yZXNwb25zZSIpCmBgYAoKYGBge3J9CmFwbGF0ZV9hbGxfMjEwIDwtCiAgcmVhZC5mbG93U2V0KHBhdGggPSAiZmxvd1NldHMvQUZCMi1kdWFsLXlXTDIxMC1kb3NlLXJlc3BvbnNlIiwgCiAgICAgICAgICAgICAgIHBoZW5vRGF0YSA9ICJhbm5vdGF0aW9uLnR4dCIpCgpwbGF0ZV9hbGxfMjEwX3N1bSA8LQogIHN1bW1hcml6ZUZsb3coYXBsYXRlX2FsbF8yMTAsIGNoYW5uZWwgPSBOQSwgZ2F0ZWQgPSBUUlVFKQpgYGAKCiMjI0Rvc2UtcmVzcG9uc2UgY3VydmUKCiMjIyMgQ29tcGFyaW5nIGxvZy1sb2dpc3RpYyBhbmQgV2VpYnVsbCBtb2RlbHMKKEZpZ3VyZSAyIGluIFJpdHogKDIwMDkpKQpgYGB7cn0KZml0ZHJjLm0xIDwtCiAgZHJtKFlMMS5BbWVhbiAvIEJMMS5BbWVhbiB+IGRvc2UsIGRhdGEgPSBwbGF0ZV9hbGxfMjEwX3N1bSwgZmN0ID0gTEwuNCgpKQpmaXRkcmMubTIgPC0KIGRybShZTDEuQW1lYW4gLyBCTDEuQW1lYW4gfiBkb3NlLCBkYXRhID0gcGxhdGVfYWxsXzIxMF9zdW0sIGZjdCA9IFcxLjQoKSkKI2ZpdGRyYy5tMyA8LSAKIyBkcm0oWUwxLkFtZWFuL0JMMS5BbWVhbn5kb3NlLCBkYXRhPXBsYXRlX2FsbF8yMTBfc3VtLCBmY3QgPSBXMi40KCkpCiNFcnJvciBpbiBkcm1PcHQob3BmY3QsIG9wZGZjdDEsIHN0YXJ0VmVjU2MsIG9wdE1ldGhvZCwgY29uc3RyYWluZWQsIHdhcm5WYWwsIDoKI0NvbnZlcmdlbmNlIGZhaWxlZAoKc3VtbWFyeShmaXRkcmMubTEpCnN1bW1hcnkoZml0ZHJjLm0yKQojc3VtbWFyeShmaXRkcmMubTMpCmBgYAoKVGhlIDQtcGFyYW1ldGVyIGxvZy1sb2dpc3RpYyBtb2RlbCBoYXMgYSBzbGlnaHRseSBsb3dlciByZXNpZHVhbCBzdGFuZGFyZCBlcnJvci4gCgpgYGB7cn0KbW9kZWwuTEw0X2FsbF8yMTAgPC0KICBkcm0oWUwxLkFtZWFuIC8gQkwxLkFtZWFuIH4gZG9zZSwKICAgICAgZGF0YSA9IHBsYXRlX2FsbF8yMTBfc3VtLAogICAgICBmY3QgPSBMTC40KG5hbWVzID0gYygKICAgICAgICAiU2xvcGUiLCAiTG93ZXIgTGltaXQiLCAiVXBwZXIgTGltaXQiLCAiRUQ1MCIKICAgICAgKSkpCnBsb3QoCiAgbW9kZWwuTEw0X2FsbF8yMTAsCiAgYnJva2VuID0gVFJVRSwKICB0eXBlID0gIm5vbmUiLAogIGx0eSA9IDEsCiAgbHdkID0gNSwKICB4bGFiID0gIkV4dHJhY2VsbHVsYXIgSUFBIGNvbmNlbnRyYXRpb24gKMK1TSkiLAogIHlsYWIgPSAiUmVzcG9uc2UgU2lnbmFsIgopCiNwbG90KG1vZGVsLkxMNF9hbGxfMjEwLCBicm9rZW4gPSBUUlVFLCBjb2wgPSAiYmxhY2siLCBhZGQ9VFJVRSkKcGxvdCgKICBtb2RlbC5MTDRfYWxsXzIxMCwKICBicm9rZW4gPSBUUlVFLAogIHR5cGUgPSAiY29uZmlkZW5jZSIsCiAgY29sID0gImJsYWNrIiwKICBhZGQgPSBUUlVFCikKc3VtbWFyeShtb2RlbC5MTDRfYWxsXzIxMCkKCmBgYAojIyMgSW5kaXZpZHVhbCByZXBsaWNhdGUgZG9zZS1yZXNwb25zZSBjdXJ2ZXMKCmBgYHtyfQpyZXBsaWNhdGUxXzIxMCA8LQogIGRybSgKICAgIFlMMS5BbWVhbiAvIEJMMS5BbWVhbiB+IGRvc2UsCiAgICBkYXRhID0gc3Vic2V0KHBsYXRlX2FsbF8yMTBfc3VtLCByZXBsaWNhdGUgPT0gIjEiKSwKICAgIGZjdCA9IExMLjQoKQogICkKcmVwbGljYXRlMl8yMTAgPC0KICBkcm0oCiAgICBZTDEuQW1lYW4gLyBCTDEuQW1lYW4gfiBkb3NlLAogICAgZGF0YSA9IHN1YnNldChwbGF0ZV9hbGxfMjEwX3N1bSwgcmVwbGljYXRlID09ICIyIiksCiAgICBmY3QgPSBMTC40KCkKICApCnJlcGxpY2F0ZTNfMjEwIDwtCiAgZHJtKAogICAgWUwxLkFtZWFuIC8gQkwxLkFtZWFuIH4gZG9zZSwKICAgIGRhdGEgPSBzdWJzZXQocGxhdGVfYWxsXzIxMF9zdW0sIHJlcGxpY2F0ZSA9PSAiMyIpLAogICAgZmN0ID0gTEwuNCgpCiAgKQpyZXBsaWNhdGU0XzIxMCA8LQogIGRybSgKICAgIFlMMS5BbWVhbiAvIEJMMS5BbWVhbiB+IGRvc2UsCiAgICBkYXRhID0gc3Vic2V0KHBsYXRlX2FsbF8yMTBfc3VtLCByZXBsaWNhdGUgPT0gIjQiKSwKICAgIGZjdCA9IExMLjQoKQogICkKcmVwbGljYXRlNV8yMTAgPC0KICBkcm0oCiAgICBZTDEuQW1lYW4gLyBCTDEuQW1lYW4gfiBkb3NlLAogICAgZGF0YSA9IHN1YnNldChwbGF0ZV9hbGxfMjEwX3N1bSwgcmVwbGljYXRlID09ICI1IiksCiAgICBmY3QgPSBMTC40KCkKICApCnJlcGxpY2F0ZTZfMjEwIDwtCiAgZHJtKAogICAgWUwxLkFtZWFuIC8gQkwxLkFtZWFuIH4gZG9zZSwKICAgIGRhdGEgPSBzdWJzZXQocGxhdGVfYWxsXzIxMF9zdW0sIHJlcGxpY2F0ZSA9PSAiNiIpLAogICAgZmN0ID0gTEwuNCgpCiAgKQpyZXBsaWNhdGU3XzIxMCA8LQogIGRybSgKICAgIFlMMS5BbWVhbiAvIEJMMS5BbWVhbiB+IGRvc2UsCiAgICBkYXRhID0gc3Vic2V0KHBsYXRlX2FsbF8yMTBfc3VtLCByZXBsaWNhdGUgPT0gIjciKSwKICAgIGZjdCA9IExMLjQoKQogICkKCnBsb3QoCiAgcmVwbGljYXRlMV8yMTAsCiAgYnJva2VuID0gVFJVRSwKICB0eXBlID0gImFsbCIsCiAgY29sID0gImRhcmsgZ3JlZW4iLAogIGx0eSA9IDIKKQpwbG90KAogIHJlcGxpY2F0ZTJfMjEwLAogIGJyb2tlbiA9IFRSVUUsCiAgYWRkID0gVFJVRSwKICB0eXBlID0gImFsbCIsCiAgY29sID0gImRhcmsgYmx1ZSIsCiAgbHR5ID0gMgopCnBsb3QoCiAgcmVwbGljYXRlM18yMTAsCiAgYnJva2VuID0gVFJVRSwKICBhZGQgPSBUUlVFLAogIHR5cGUgPSAiYWxsIiwKICBjb2wgPSAieWVsbG93IiwKICBsdHkgPSAyCikKcGxvdCgKICByZXBsaWNhdGU0XzIxMCwKICBicm9rZW4gPSBUUlVFLAogIGFkZCA9IFRSVUUsCiAgdHlwZSA9ICJhbGwiLAogIGNvbCA9ICJkYXJrIGdyZXkiLAogIGx0eSA9IDIKKQpwbG90KAogIHJlcGxpY2F0ZTVfMjEwLAogIGJyb2tlbiA9IFRSVUUsCiAgYWRkID0gVFJVRSwKICB0eXBlID0gImFsbCIsCiAgY29sID0gImRhcmsgb3JhbmdlIiwKICBsdHkgPSAyCikKcGxvdCgKICByZXBsaWNhdGU2XzIxMCwKICBicm9rZW4gPSBUUlVFLAogIGFkZCA9IFRSVUUsCiAgdHlwZSA9ICJhbGwiLAogIGNvbCA9ICJicm93biIsCiAgbHR5ID0gMgopCnBsb3QoCiAgcmVwbGljYXRlN18yMTAsCiAgYnJva2VuID0gVFJVRSwKICBhZGQgPSBUUlVFLAogIHR5cGUgPSAiYWxsIiwKICBjb2wgPSAiZGFyayByZWQiLAogIGx0eSA9IDIKKQpwbG90KAogIG1vZGVsLkxMNF9hbGxfMjEwLAogIGJyb2tlbiA9IFRSVUUsCiAgYWRkID0gVFJVRSwKICB0eXBlID0gIm5vbmUiLAogIGx0eSA9IDEsCiAgbHdkID0gNSwKICB4bGFiID0gIkV4dHJhY2VsbHVsYXIgSUFBIGNvbmNlbnRyYXRpb24gKMK1TSkiLAogIHlsYWIgPSAiUmVzcG9uc2UgU2lnbmFsIgopCiNwbG90KG1vZGVsLkxMNF9hbGxfMjEwLCBicm9rZW4gPSBUUlVFLCBjb2wgPSAiYmxhY2siLCBhZGQ9VFJVRSkKcGxvdCgKICBtb2RlbC5MTDRfYWxsXzIxMCwKICBicm9rZW4gPSBUUlVFLAogIHR5cGUgPSAiY29uZmlkZW5jZSIsCiAgY29sID0gImJsYWNrIiwKICBhZGQgPSBUUlVFCikKCmBgYAoKIyMgVElSMS1iYXNlZCBiaW9zZW5zb3IgKHlXTDIwOSBUSVIgZHVhbC1mdXNpb24sIHNpbmdsZSByYXRpb21ldHJpYyBjb25zdHJ1Y3QpCgpgYGB7ciwgZXZhbCA9IEZ9CnBsYXRlX2FsbF8yMDkgPC0KICByZWFkLnBsYXRlU2V0KHBhdGggPSAifi9Hb29nbGUgRHJpdmUvU2hhcmVkIGRyaXZlcy9QbGFudFN5bkJpb0xhYi9QYXQvRXhwZXJpbWVudHMvRG9lcy1yZXNwb25zZSBhc3NheS8xMTIxMjAyMl9EUkFfb3ZlcmxheWRhdGEvQ29tYmluZSBEYXRhX3lXTDIwOS8iLCBwYXR0ZXJuID0gIkRSQS0qIikgCmBgYAoKYGBge3IsIGV2YWwgPSBGfQphbm5vdGF0aW9uIDwtIGNyZWF0ZUFubm90YXRpb24oeW91ckZsb3dTZXQgPSBwbGF0ZV9hbGxfMjA5KQp3cml0ZS5jc3YoCiAgYW5ub3RhdGlvbiwKICAnL1VzZXJzL3BhdGNoYWlzdXBhL0dvb2dsZSBEcml2ZS9TaGFyZWQgZHJpdmVzL1BsYW50U3luQmlvTGFiL1BhdC9FeHBlcmltZW50cy9Eb2VzLXJlc3BvbnNlIGFzc2F5LzExMjEyMDIyX0RSQV9vdmVybGF5ZGF0YS9vdmVybGF5ZGF0YV9hbm5vdGF0aW9uX3lXTDIwOS5jc3YnCikKYGBgCgpgYGB7ciwgZXZhbCA9IEZ9CmFubm90YXRpb24gPC0KICByZWFkLmNzdigKICAgICd+L0dvb2dsZSBEcml2ZS9TaGFyZWQgZHJpdmVzL1BsYW50U3luQmlvTGFiL1BhdC9FeHBlcmltZW50cy9Eb2VzLXJlc3BvbnNlIGFzc2F5LzExMjEyMDIyX0RSQV9vdmVybGF5ZGF0YS9vdmVybGF5ZGF0YV9hbm5vdGF0aW9uX3lXTDIwOS5jc3YnCiAgKQoKYXBsYXRlX2FsbF8yMDkgPC0KICBhbm5vdGF0ZUZsb3dTZXQoeW91ckZsb3dTZXQgPSBwbGF0ZV9hbGxfMjA5LAogICAgICAgICAgICAgICAgICBhbm5vdGF0aW9uX2RmID0gYW5ub3RhdGlvbiwKICAgICAgICAgICAgICAgICAgbWVyZ2VCeSA9ICduYW1lJykKaGVhZChyb3duYW1lcyhwRGF0YShhcGxhdGVfYWxsXzIwOSkpKQpoZWFkKHBEYXRhKGFwbGF0ZV9hbGxfMjA5KSkKCndyaXRlLmZsb3dTZXQoYXBsYXRlX2FsbF8yMDksIG91dGRpciA9ICJmbG93U2V0cy9USVIxLWR1YWwteVdMMjA5LWRvc2UtcmVzcG9uc2UiKQpgYGAKCmBgYHtyfQphcGxhdGVfYWxsXzIwOSA8LQogIHJlYWQuZmxvd1NldChwYXRoID0gImZsb3dTZXRzL1RJUjEtZHVhbC15V0wyMDktZG9zZS1yZXNwb25zZSIsIAogICAgICAgICAgICAgICBwaGVub0RhdGEgPSAiYW5ub3RhdGlvbi50eHQiKQoKZGF0X3N1bV9vdmVybGF5ZGF0YV8yMDkgPC0KICBzdW1tYXJpemVGbG93KGFwbGF0ZV9hbGxfMjA5LCBnYXRlZCA9IFRSVUUpCmBgYAojIyNEb3NlLXJlc3BvbnNlIGN1cnZlCmBgYHtyfQptb2RlbC5MTDRfcmVwMV8yMDkgPC0KICBkcm0oCiAgICBZTDEuQW1lYW4gLyBCTDEuQW1lYW4gfiBkb3NlLAogICAgZGF0YSA9IHN1YnNldChkYXRfc3VtX292ZXJsYXlkYXRhXzIwOSwgcmVwbGljYXRlID09ICIxIiksCiAgICBmY3QgPSBMTC40KG5hbWVzID0gYygKICAgICAgIlNsb3BlIiwgIkxvd2VyIExpbWl0IiwgIlVwcGVyIExpbWl0IiwgIkVENTAiCiAgICApKQogICkKcGxvdCgKICBtb2RlbC5MTDRfcmVwMV8yMDksCiAgdHlwZSA9ICJhbGwiLAogIGNvbCA9ICJyZWQiLAogIGx0eSA9IDEsCiAgbHdkID0gMiwKICB4bGFiID0gIkV4dHJhY2VsbHVsYXIgSUFBIGNvbmNlbnRyYXRpb24gKMK1TSkiLAogIHlsYWIgPSAiUmVkL0dyZWVuIEZsdW9yZXNjZW50IFJhdGlvIgopCnBsb3QoCiAgbW9kZWwuTEw0X3JlcDFfMjA5LAogIGJyb2tlbiA9IFRSVUUsCiAgdHlwZSA9ICJjb25maWRlbmNlIiwKICBjb2wgPSAicmVkIiwKICBhZGQgPSBUUlVFCikKcHJpbnQoc3VtbWFyeShtb2RlbC5MTDRfcmVwMV8yMDkpKQoKCm1vZGVsLkxMNF9yZXAyXzIwOSA8LQogIGRybSgKICAgIFlMMS5BbWVhbiAvIEJMMS5BbWVhbiB+IGRvc2UsCiAgICBkYXRhID0gc3Vic2V0KGRhdF9zdW1fb3ZlcmxheWRhdGFfMjA5LCByZXBsaWNhdGUgPT0gIjIiKSwKICAgIGZjdCA9IExMLjQobmFtZXMgPSBjKAogICAgICAiU2xvcGUiLCAiTG93ZXIgTGltaXQiLCAiVXBwZXIgTGltaXQiLCAiRUQ1MCIKICAgICkpCiAgKQpwbG90KAogIG1vZGVsLkxMNF9yZXAyXzIwOSwKICB0eXBlID0gImFsbCIsCiAgY29sID0gImJsdWUiLAogIGx0eSA9IDEsCiAgbHdkID0gMiwKICB4bGFiID0gIkV4dHJhY2VsbHVsYXIgSUFBIGNvbmNlbnRyYXRpb24gKMK1TSkiLAogIHlsYWIgPSAiUmVkL0dyZWVuIEZsdW9yZXNjZW50IFJhdGlvIgopCnBsb3QoCiAgbW9kZWwuTEw0X3JlcDJfMjA5LAogIGJyb2tlbiA9IFRSVUUsCiAgdHlwZSA9ICJjb25maWRlbmNlIiwKICBjb2wgPSAiYmx1ZSIsCiAgYWRkID0gVFJVRQopCnByaW50KHN1bW1hcnkobW9kZWwuTEw0X3JlcDJfMjA5KSkKCgptb2RlbC5MTDRfcmVwM18yMDkgPC0KICBkcm0oCiAgICBZTDEuQW1lYW4gLyBCTDEuQW1lYW4gfiBkb3NlLAogICAgZGF0YSA9IHN1YnNldChkYXRfc3VtX292ZXJsYXlkYXRhXzIwOSwgcmVwbGljYXRlID09ICIzIiksCiAgICBmY3QgPSBMTC40KG5hbWVzID0gYygKICAgICAgIlNsb3BlIiwgIkxvd2VyIExpbWl0IiwgIlVwcGVyIExpbWl0IiwgIkVENTAiCiAgICApKQogICkKcGxvdCgKICBtb2RlbC5MTDRfcmVwM18yMDksCiAgdHlwZSA9ICJhbGwiLAogIGNvbCA9ICJkYXJrIGdyZWVuIiwKICBsdHkgPSAxLAogIGx3ZCA9IDIsCiAgeGxhYiA9ICJFeHRyYWNlbGx1bGFyIElBQSBjb25jZW50cmF0aW9uICjCtU0pIiwKICB5bGFiID0gIlJlZC9HcmVlbiBGbHVvcmVzY2VudCBSYXRpbyIKKQpwbG90KAogIG1vZGVsLkxMNF9yZXAzXzIwOSwKICBicm9rZW4gPSBUUlVFLAogIHR5cGUgPSAiY29uZmlkZW5jZSIsCiAgY29sID0gImRhcmsgZ3JlZW4iLAogIGFkZCA9IFRSVUUKKQoKcHJpbnQoc3VtbWFyeShtb2RlbC5MTDRfcmVwM18yMDkpKQoKCgptb2RlbC5MTDRfYWxsXzIwOSA8LQogIGRybShZTDEuQW1lYW4gLyBCTDEuQW1lYW4gfiBkb3NlLAogICAgICBkYXRhID0gZGF0X3N1bV9vdmVybGF5ZGF0YV8yMDksCiAgICAgIGZjdCA9IExMLjQobmFtZXMgPSBjKAogICAgICAgICJTbG9wZSIsICJMb3dlciBMaW1pdCIsICJVcHBlciBMaW1pdCIsICJFRDUwIgogICAgICApKSkKcGxvdCgKICBtb2RlbC5MTDRfYWxsXzIwOSwKICB0eXBlID0gImFsbCIsCiAgY29sID0gImJsYWNrIiwKICBsdHkgPSAxLAogIGx3ZCA9IDMKKQpwbG90KAogIG1vZGVsLkxMNF9hbGxfMjA5LAogIGJyb2tlbiA9IFRSVUUsCiAgY29sID0gImJsYWNrIiwKICBhZGQgPSBUUlVFCikKcGxvdCgKICBtb2RlbC5MTDRfYWxsXzIwOSwKICBicm9rZW4gPSBUUlVFLAogIHR5cGUgPSAiY29uZmlkZW5jZSIsCiAgY29sID0gImJsYWNrIiwKICBhZGQgPSBUUlVFCikKcHJpbnQoc3VtbWFyeShtb2RlbC5MTDRfYWxsXzIwOSkpCgpyZXBsaWNhdGUxXzIwOSA8LQogIGRybSgKICAgIFlMMS5BbWVhbiAvIEJMMS5BbWVhbiB+IGRvc2UsCiAgICBkYXRhID0gc3Vic2V0KGRhdF9zdW1fb3ZlcmxheWRhdGFfMjA5LCByZXBsaWNhdGUgPT0gIjEiKSwKICAgIGZjdCA9IExMLjQoKQogICkKcmVwbGljYXRlMl8yMDkgPC0KICBkcm0oCiAgICBZTDEuQW1lYW4gLyBCTDEuQW1lYW4gfiBkb3NlLAogICAgZGF0YSA9IHN1YnNldChkYXRfc3VtX292ZXJsYXlkYXRhXzIwOSwgcmVwbGljYXRlID09ICIyIiksCiAgICBmY3QgPSBMTC40KCkKICApCnJlcGxpY2F0ZTNfMjA5IDwtCiAgZHJtKAogICAgWUwxLkFtZWFuIC8gQkwxLkFtZWFuIH4gZG9zZSwKICAgIGRhdGEgPSBzdWJzZXQoZGF0X3N1bV9vdmVybGF5ZGF0YV8yMDksIHJlcGxpY2F0ZSA9PSAiMyIpLAogICAgZmN0ID0gTEwuNCgpCiAgKQoKCnBsb3QoCiAgcmVwbGljYXRlMV8yMDksCiAgYnJva2VuID0gVFJVRSwKICBhZGQgPSBUUlVFLAogIHR5cGUgPSAibm9uZSIsCiAgY29sID0gInJlZCIsCiAgbHR5ID0gMgopCnBsb3QoCiAgcmVwbGljYXRlMl8yMDksCiAgYnJva2VuID0gVFJVRSwKICBhZGQgPSBUUlVFLAogIHR5cGUgPSAibm9uZSIsCiAgY29sID0gImJsdWUiLAogIGx0eSA9IDIKKQpwbG90KAogIHJlcGxpY2F0ZTNfMjA5LAogIGJyb2tlbiA9IFRSVUUsCiAgYWRkID0gVFJVRSwKICB0eXBlID0gIm5vbmUiLAogIGNvbCA9ICJkYXJrIGdyZWVuIiwKICBsdHkgPSAyCikKCmBgYAoKIyMgQ29tYmluZWQgRG9zZS1yZXNwb25zZSBjdXJ2ZXN3aXRoIGdncGxvdAoKYGBge3J9CnBtMjEwIDwtCiAgZXhwYW5kLmdyaWQodHJlYXRtZW50ID0gZXhwKHNlcShsb2coMWUtNSksIGxvZygxZTIpLCBsZW5ndGggPSAxMDAwKSkpCnBtMjEwIDwtCiAgY2JpbmQocG0yMTAsCiAgICAgICAgcHJlZGljdChtb2RlbC5MTDRfYWxsXzIxMCwgbmV3ZGF0YSA9IHBtMjEwLCBpbnRlcnZhbCA9ICJjb25maWRlbmNlIikpICAKCnBsb3QyMTAgPC0KICBnZ3Bsb3QocGxhdGVfYWxsXzIxMF9zdW0sIGFlcyh4ID0gZG9zZSwgeSA9IFlMMS5BbWVhbiAvIEJMMS5BbWVhbikpICArIAogIHNjYWxlX3hfbG9nMTAoKSArIGdlb21fcmliYm9uKAogICAgZGF0YSA9IHBtMjEwLAogICAgYWVzKAogICAgICB4ID0gdHJlYXRtZW50LAogICAgICB5ID0gUHJlZGljdGlvbiwKICAgICAgeW1pbiA9IExvd2VyLAogICAgICB5bWF4ID0gVXBwZXIKICAgICksCiAgICBhbHBoYSA9IDAuNAogICkgKyBnZW9tX2xpbmUoZGF0YSA9IHBtMjEwLAogICAgICAgICAgICAgICAgYWVzKHggPSB0cmVhdG1lbnQsIHkgPSBQcmVkaWN0aW9uKSwKICAgICAgICAgICAgICAgIGxpbmV3aWR0aCA9IDEuMikgKyB5bGFiKCJtU2NhcmxldC1JL1ZlbnVzIikgKyB4bGFiKCJBdXhpbiAoSUFBLCDCtU0pIikgKyAKICBzY2FsZV94X2xvZzEwKGxhYmVscyA9IAogICAgICAgICAgICAgICAgICBzY2FsZXM6OmxhYmVsX251bWJlcihkcm9wMHRyYWlsaW5nID0gVFJVRSkpICsgIAogIHNjYWxlX2NvbG9yX3ZpcmlkaXNfYygpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvciA9IHJlcGxpY2F0ZSksIHNpemUgPSAxLCBhbHBoYSA9IDAuNikgKyAKICB0aGVtZV9jbGFzc2ljKCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsIAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLAogICAgICAgIHBsb3QudGl0bGUucG9zaXRpb24gPSAicGxvdCIpICsgCiAgZ2d0aXRsZSgiQUZCMiIpICAKcGxvdDIxMAoKCnBtMjA5IDwtCiAgZXhwYW5kLmdyaWQodHJlYXRtZW50ID0gZXhwKHNlcShsb2coMWUtNSksIGxvZygxZTIpLCBsZW5ndGggPSAxMDAwKSkpCnBtMjA5IDwtCiAgY2JpbmQocG0yMDksCiAgICAgICAgcHJlZGljdChtb2RlbC5MTDRfYWxsXzIwOSwgbmV3ZGF0YSA9IHBtMjA5LCBpbnRlcnZhbCA9ICJjb25maWRlbmNlIikpCgpwbG90MjA5IDwtCiAgZ2dwbG90KGRhdF9zdW1fb3ZlcmxheWRhdGFfMjA5LCBhZXMoeCA9IGRvc2UsIHkgPSBZTDEuQW1lYW4gLyBCTDEuQW1lYW4pKSAgKyAKICBzY2FsZV94X2xvZzEwKCkgKyBnZW9tX3JpYmJvbigKICAgIGRhdGEgPSBwbTIwOSwKICAgIGFlcygKICAgICAgeCA9IHRyZWF0bWVudCwKICAgICAgeSA9IFByZWRpY3Rpb24sCiAgICAgIHltaW4gPSBMb3dlciwKICAgICAgeW1heCA9IFVwcGVyCiAgICApLAogICAgYWxwaGEgPSAwLjQKICApICsgZ2VvbV9saW5lKGRhdGEgPSBwbTIwOSwKICAgICAgICAgICAgICAgIGFlcyh4ID0gdHJlYXRtZW50LCB5ID0gUHJlZGljdGlvbiksCiAgICAgICAgICAgICAgICBsaW5ld2lkdGggPSAxLjIpICsgCiAgeWxhYigibVNjYXJsZXQtSS9WZW51cyIpICsgCiAgeGxhYigiQXV4aW4gKElBQSwgwrVNKSIpICsgCiAgc2NhbGVfeF9sb2cxMChsYWJlbHMgPSAKICAgICAgICAgICAgICAgICAgc2NhbGVzOjpsYWJlbF9udW1iZXIoZHJvcDB0cmFpbGluZyA9IFRSVUUpKSArIAogIHNjYWxlX2NvbG9yX3ZpcmlkaXNfYygpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvciA9IHJlcGxpY2F0ZSksIHNpemUgPSAxLCBhbHBoYSA9IDAuNikgKwogIHRoZW1lX2NsYXNzaWMoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksCiAgICAgICAgcGxvdC50aXRsZS5wb3NpdGlvbiA9ICJwbG90IikgKyAKICAjeWxpbSgwLjA5NSwgMC4xMikgKyAKICBnZ3RpdGxlKCJUSVIxIikKcGxvdDIwOQoKcGxvdDIxMCArIHBsb3QyMDkgKyBwYXRjaHdvcms6OnBsb3RfYW5ub3RhdGlvbih0YWdfbGV2ZWxzID0gIkEiKQoKZ2dzYXZlKAogIHBsb3QgPSBwbG90MjEwICsgcGxvdDIwOSArIHBhdGNod29yazo6cGxvdF9hbm5vdGF0aW9uKHRhZ19sZXZlbHMgPSAiQSIpLAogIGZpbGVuYW1lID0gImRvc2UtcmVzcG9uc2UucGRmIiwKICB3aWR0aCA9IDYsCiAgaGVpZ2h0ID0gMwopCmdnc2F2ZSgKICBwbG90ID0gcGxvdDIxMCArIHBsb3QyMDkgKyBwYXRjaHdvcms6OnBsb3RfYW5ub3RhdGlvbih0YWdfbGV2ZWxzID0gIkEiKSwKICBmaWxlbmFtZSA9ICJkb3NlLXJlc3BvbnNlLnBuZyIsCiAgd2lkdGggPSA2LAogIGhlaWdodCA9IDMKKQpgYGAKCiMgTENNUyBtZWFzdXJlbWVudHMgb2YgaW50cmFjZWxsdWxhciBhdXhpbgoKYGBge3IsIGV2YWw9RkFMU0V9CnBsYXRlXzA4MDUyMDIyIDwtIHJlYWQucGxhdGVTZXQocGF0aCA9ICJ+L0dvb2dsZSBEcml2ZS9TaGFyZWQgZHJpdmVzL1BsYW50U3luQmlvTGFiL1BhdC9FeHBlcmltZW50cy9Eb2VzLXJlc3BvbnNlIGFzc2F5LzA4MDUyMDIyX3lXTDIxMF9EUkEtTENNUy1SMi9BbGxkYXRhLyIsIHBhdHRlcm4gPSAiRFJBKiIpIApgYGAKCmBgYHtyLCBldmFsPUZBTFNFfQphbm5vdGF0aW9uIDwtIHJlYWQuY3N2KCd+L0dvb2dsZSBEcml2ZS9TaGFyZWQgZHJpdmVzL1BsYW50U3luQmlvTGFiL1BhdC9FeHBlcmltZW50cy9Eb2VzLXJlc3BvbnNlIGFzc2F5LzA4MDUyMDIyX3lXTDIxMF9EUkEtTENNUy1SMi8wODA1MjAyMl9hbGxkYXRhX2Fubm90YXRpb24uY3N2JykKCmFwbGF0ZV8wODA1MjAyMiA8LSBhbm5vdGF0ZUZsb3dTZXQoeW91ckZsb3dTZXQgPSBwbGF0ZV8wODA1MjAyMiwgYW5ub3RhdGlvbl9kZiA9IGFubm90YXRpb24sIG1lcmdlQnkgPSAnbmFtZScpCmhlYWQocm93bmFtZXMocERhdGEoYXBsYXRlXzA4MDUyMDIyKSkpCmhlYWQocERhdGEoYXBsYXRlXzA4MDUyMDIyKSkKd3JpdGUuZmxvd1NldChhcGxhdGVfMDgwNTIwMjIsICJmbG93U2V0cy9BRkIyLWR1YWwtRFItTENNUyIpCmBgYApgYGB7cn0KYXBsYXRlXzA4MDUyMDIyIDwtIHJlYWQuZmxvd1NldChwYXRoID0gImZsb3dTZXRzL0FGQjItZHVhbC1EUi1MQ01TIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaGVub0RhdGEgPSAiYW5ub3RhdGlvbi50eHQiKQpwbGF0ZV8wODA1MjAyMl9zdW0gPC0gc3VtbWFyaXplRmxvdyhhcGxhdGVfMDgwNTIwMjIsIGdhdGVkID0gVFJVRSkKbW9kZWwuTEw0XzA4MDUyMDIyPC0gZHJtKFlMMS5BbWVhbi9CTDEuQW1lYW5+ZG9zZSwgZGF0YT1zdWJzZXQocGxhdGVfMDgwNTIwMjJfc3VtLCByZWFkaW5nID09IjEwIiksIGZjdD1MTC40KG5hbWVzID0gYygiU2xvcGUiLCAiTG93ZXIgTGltaXQiLCAiVXBwZXIgTGltaXQiLCAiRUQ1MCIpKSkKc3VtbWFyeShtb2RlbC5MTDRfMDgwNTIwMjIpCnBtXzA4MDUyMDIyIDwtIGV4cGFuZC5ncmlkKHRyZWF0bWVudD1leHAoc2VxKGxvZygxZS0zKSwgbG9nKDFlMiksIGxlbmd0aD0xMDAwKSkpIApwbV8wODA1MjAyMiA8LSBjYmluZChwbV8wODA1MjAyMixwcmVkaWN0KG1vZGVsLkxMNF8wODA1MjAyMiwgbmV3ZGF0YT1wbV8wODA1MjAyMiwgaW50ZXJ2YWw9ImNvbmZpZGVuY2UiKSkgIAoKcGxvdF8wODA1MjAyMiA8LSAKICBnZ3Bsb3QoZGF0YT1zdWJzZXQocGxhdGVfMDgwNTIwMjJfc3VtLCByZWFkaW5nID09IjEwIiksIAogICAgICAgICBhZXMoeCA9IGRvc2UsIHkgPSBZTDEuQW1lYW4vQkwxLkFtZWFuKSkgICsgCiAgZ2VvbV9yaWJib24oZGF0YSA9IHBtXzA4MDUyMDIyLCAKICAgICAgICAgICAgICBhZXMoeCA9IHRyZWF0bWVudCwgeSA9IFByZWRpY3Rpb24sIHltaW4gPSBMb3dlciwKICAgICAgICAgICAgICAgICAgeW1heD1VcHBlciksIGFscGhhPTAuNCkgKyAKICBnZW9tX2xpbmUoZGF0YSA9IHBtXzA4MDUyMDIyLCAKICAgICAgICAgICAgYWVzKHggPSB0cmVhdG1lbnQsIHkgPSBQcmVkaWN0aW9uKSkgKyAKICB4bGFiKCJFeHRyYWNlbGx1bGFyIElBQSAowrVNKSIpICsKICB5bGFiKCJBRkIyLW1TY2FybGV0LS9WZW51cy1JQUExNyIpICsgCiAgc2NhbGVfeF9sb2cxMChsYWJlbHMgPSAKICAgICAgICAgICAgICAgICAgc2NhbGVzOjpsYWJlbF9udW1iZXIoZHJvcDB0cmFpbGluZyA9IFRSVUUpKSArICAKICBnZW9tX3BvaW50KGNvbG9yID0gImJsYWNrIikgKyAKICB0aGVtZV9jbGFzc2ljKGJhc2Vfc2l6ZSA9IDEyKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSAKcGxvdF8wODA1MjAyMgoKTENNU2RhdGEgPC0gcmVhZC5jc3YoJzA4MDUyMDIyX3lXTDIxMF9EUkEtTENNU19kYXRhLmNzdicpCgptb2RlbC5MTDRfMDgwNTIwMjJfTENNUzwtIGRybShPYnNlcnZlZF9JQUFfaW5fdU1+RG9zZV9JQUEsIGRhdGE9TENNU2RhdGEsIGZjdD1MTC40KG5hbWVzID0gYygiU2xvcGUiLCAiTG93ZXIgTGltaXQiLCAiVXBwZXIgTGltaXQiLCAiRUQ1MCIpKSkKc3VtbWFyeShtb2RlbC5MTDRfMDgwNTIwMjJfTENNUykKCnBsb3QobW9kZWwuTEw0XzA4MDUyMDIyX0xDTVMsIHR5cGU9ImFsbCIsY29sPSJibGFjayIsbHR5PTEsIGx3ZD0zLCB4bGFiID0gIkV4dHJhY2VsbHVsYXIgY29uY2VudHJhdGlvbnMgb2YgSUFBICh1TSkiLCB5bGFiID0gIk9ic2VydmVkIElBQSAodU0pIikKCnBtXzA4MDUyMDIyX0xDTVMgPC0gZXhwYW5kLmdyaWQodHJlYXRtZW50PWV4cChzZXEobG9nKDFlLTMpLCBsb2coNWUyKSwgbGVuZ3RoPTEwMDApKSkgCnBtXzA4MDUyMDIyX0xDTVMgPC0gY2JpbmQocG1fMDgwNTIwMjJfTENNUywKICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVkaWN0KG1vZGVsLkxMNF8wODA1MjAyMl9MQ01TLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3ZGF0YT1wbV8wODA1MjAyMl9MQ01TLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJ2YWw9ImNvbmZpZGVuY2UiKSkgCkxDTVNfaW50cmFjZWxsdWxhciA8LSAKZ2dwbG90KGRhdGEgPSBMQ01TZGF0YSwgCiAgICAgICBtYXBwaW5nID0gYWVzKHggPSBEb3NlX0lBQSwgCiAgICAgICAgICAgICAgICAgICAgIHkgPSBPYnNlcnZlZF9JQUFfaW5fdU0pKSArIAogIGdlb21fcG9pbnQoKSArIAogIGdlb21fcmliYm9uKGRhdGEgPSBwbV8wODA1MjAyMl9MQ01TLCAKICAgICAgICAgICAgICBhZXMoeCA9IHRyZWF0bWVudCwgeSA9IFByZWRpY3Rpb24sIHltaW4gPSBMb3dlciwKICAgICAgICAgICAgICAgICAgeW1heD1VcHBlciksIGFscGhhPTAuNCkgKyAKICBnZW9tX2xpbmUoZGF0YSA9IHBtXzA4MDUyMDIyX0xDTVMsIAogICAgICAgICAgICBhZXMoeCA9IHRyZWF0bWVudCwgeSA9IFByZWRpY3Rpb24pKSArCiAgc2NhbGVfeF9sb2cxMChsYWJlbHMgPSAKICAgICAgICAgICAgICAgIHNjYWxlczo6bGFiZWxfbnVtYmVyKGRyb3AwdHJhaWxpbmcgPSBUUlVFKSkgKwogIHRoZW1lX2NsYXNzaWMoYmFzZV9zaXplID0gMTMpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsgCiAgeWxhYigiSW50cmFjZWxsdWxhciBJQUEgKMK1TSkiKSArIAogIHhsYWIoIkV4dHJhY2VsbHVsYXIgSUFBICjCtU0pIikgIAoKcGxvdF8wODA1MjAyMiArIExDTVNfaW50cmFjZWxsdWxhciArIAogIHBsb3RfYW5ub3RhdGlvbih0YWdfbGV2ZWxzID0gIkEiKQpnZ3NhdmUoIkxDTVMtY29tcGFyaXNvbi5wZGYiLCB3aWR0aD02LCBoZWlnaHQgPSAzKQpnZ3NhdmUoIkxDTVMtY29tcGFyaXNvbi5wbmciLCB3aWR0aD02LCBoZWlnaHQgPSAzKQpgYGAKCiMgQXV4aW4taW5kdWNlZCBkZWdyYWRhdGlvbiB0aW1lLWNvdXJzZSBhc3NheSBmb3IgdGhlIGR1YWwtZnVzaW9uIGJpb3NlbnNvcnMgaW4gZGlmZmVyZW50IHllYXN0IHN0cmFpbnMKClR3byBpc29sYXRlZCBjb2xvbmllcyBmcm9tIGVhY2ggc3RyYWluIHdlcmUgc2VsZWN0ZWQgYXQgcmFuZG9tIGFuZCB0ZXN0ZWQgaW4gYXV4aW4taW5kdWNlZCBwcm90ZWluIGRlZ3JhZGF0aW9uIGFzc2F5LiBJQUEgd29ya2luZyBzb2x1dGlvbiB3YXMgYWRkZWQgdG8gb2J0YWluIHRoZSBJQUEgY29uY2VudHJhdGlvbiBhdCA1MCDCtU0gaW4gZWFjaCBjdWx0dXJlLiBUaGUgYXNzYXkgd2FzIGNhcnJpZWQgb3V0IHVzaW5nIFRoZXJtb0Zpc2hlciBBdHR1bmUgTnhUIEIvWSBmbG93IGN5dG9tZXRlci4KClN0cmFpbnM6CgotICAgeVdMMTg1IChUSVIxIGR1YWwtZnVzaW9uIGluIFczMDMpCi0gICB5V0wxODYgKEFGQjIgZHVhbC1mdXNpb24gaW4gVzMwMykKLSAgIHlXTDIwOSAoVElSMSBkdWFsLWZ1c2lvbiBpbiBZUEg0OTkpCi0gICB5V0wyMTAgKEFGQjIgZHVhbC1mdXNpb24gaW4gWVBINDk5KQoKYGBge3IsIGV2YWwgPSBGQUxTRX0KcGxhdGVfMDMxMTIwMjIgPC0gcmVhZC5wbGF0ZVNldChwYXRoID0gIn4vR29vZ2xlIERyaXZlL1NoYXJlZCBkcml2ZXMvUGxhbnRTeW5CaW9MYWIvUGF0L0V4cGVyaW1lbnRzL1RpbWUgY291cnNlIGFzc2F5cy8wMzExMjAyMl9UaW1lLWNvdXJzZSBhc3NheS8xMHJlYWRpbmdzL29ubHlQYXRzdHJhaW5zLyIsIHBhdHRlcm4gPSAiVENBKiIpIApgYGAKCmBgYHtyLCBldmFsID0gRn0KYW5ub3RhdGlvbiA8LSBjcmVhdGVBbm5vdGF0aW9uKHlvdXJGbG93U2V0ID0gcGxhdGVfMDMxMTIwMjIpCndyaXRlLmNzdihhbm5vdGF0aW9uLCd+L0dvb2dsZSBEcml2ZS9TaGFyZWQgZHJpdmVzL1BsYW50U3luQmlvTGFiL1BhdC9FeHBlcmltZW50cy9UaW1lIGNvdXJzZSBhc3NheXMvMDMxMTIwMjJfVGltZS1jb3Vyc2UgYXNzYXkvMDMxMTIwMjJfVGltZS1jb3Vyc2UgYXNzYXlfMTBwbGF0ZXNQYXRTdHJhaW5zMi5jc3YnKQpgYGAKCmBgYHtyLCBldmFsID0gRn0KYW5ub3RhdGlvbiA8LSByZWFkLmNzdignfi9Hb29nbGUgRHJpdmUvU2hhcmVkIGRyaXZlcy9QbGFudFN5bkJpb0xhYi9QYXQvRXhwZXJpbWVudHMvVGltZSBjb3Vyc2UgYXNzYXlzLzAzMTEyMDIyX1RpbWUtY291cnNlIGFzc2F5LzAzMTEyMDIyX1RpbWUtY291cnNlIGFzc2F5XzEwcGxhdGVzUGF0U3RyYWluczIuY3N2JykKYXBsYXRlXzAzMTEyMDIyIDwtIGFubm90YXRlRmxvd1NldCh5b3VyRmxvd1NldCA9IHBsYXRlXzAzMTEyMDIyLCBhbm5vdGF0aW9uX2RmID0gYW5ub3RhdGlvbiwgbWVyZ2VCeSA9ICduYW1lJykKaGVhZChyb3duYW1lcyhwRGF0YShhcGxhdGVfMDMxMTIwMjIpKSkKaGVhZChwRGF0YShhcGxhdGVfMDMxMTIwMjIpKQoKd3JpdGUuZmxvd1NldChhcGxhdGVfMDMxMTIwMjIsIG91dGRpciA9ICJmbG93U2V0cy9kdWFsLXRpbWUtY291cnNlIikKYGBgCgpgYGB7cn0KYXBsYXRlXzAzMTEyMDIyIDwtCiAgcmVhZC5mbG93U2V0KHBhdGggPSAiZmxvd1NldHMvZHVhbC10aW1lLWNvdXJzZS8iLCBwaGVub0RhdGEgPSAiYW5ub3RhdGlvbi50eHQiKQpwbGF0ZV8wMzExMjAyMl9zdW0gPC0gc3VtbWFyaXplRmxvdyhhcGxhdGVfMDMxMTIwMjIsIGdhdGVkID0gVFJVRSkKCgpwbGF0ZV8wMzExMjAyMl9zdW0gPC0KICBwbGF0ZV8wMzExMjAyMl9zdW0gJT4lIG11dGF0ZSgKICAgIGJhY2tncm91bmRfcCA9IGNhc2Vfd2hlbigKICAgICAgc3RyYWluICVpbiUgYygieVdMMTg1IiwgInlXTDE4NiIpIH4gIlczMDMiLAogICAgICBzdHJhaW4gJWluJSBjKCJ5V0wyMDkiLCAieVdMMjEwIikgfiAiWVBINDk5IgogICAgKSwKICAgIHJlY2VwdG9yX3AgPSBjYXNlX3doZW4oCiAgICAgIHN0cmFpbiAlaW4lIGMoInlXTDE4NSIsICJ5V0wyMDkiKSB+ICJUSVIxIiwKICAgICAgc3RyYWluICVpbiUgYygieVdMMTg2IiwgInlXTDIxMCIpIH4gIkFGQjIiCiAgICApCiAgKQpgYGAKCmBgYHtyfQojVGhlIHRpbWUgYXV4aW4gYWRkaXRpb24gaXMgZXF1YWwgdG8gdGltZSB6ZXJvCnRpbWUwIDwtCiAgIjMwMzExMjAyMi1QYXQtVENBMDNfVGltZS1jb3Vyc2UgYXNzYXlfQXV4aW5feVdMMTg1LUMxLmZjcyIKIyBvciB3aGF0ZXZlciB3ZWxsIHdhcyBiZWluZyByZWFkIHdoZW4gYXV4aW4gd2FzIGFkZGVkCgpwbGF0ZV8wMzExMjAyMl9zdW0kdGltZSA8LQogIHBsYXRlXzAzMTEyMDIyX3N1bSRidGltZSAtIAogIHBsYXRlXzAzMTEyMDIyX3N1bVtbd2hpY2gocGxhdGVfMDMxMTIwMjJfc3VtJG5hbWUgPT0gdGltZTApLCAiYnRpbWUiXV0KI3NpbmdsZSBicmFja2V0IC0tPmV4dHJhY3RpbmcgdGhlIGFsbCBuYW1lLCAyIGJyYWNrZXRzIGV4dHJhY3QganVzdCBzaW5nbGUgInZhbHVlIiBvciAidmFsdWVzIgoKYGBgCgpgYGB7cn0KI1RvIG5vcm1hbGl6ZSBkYXRhCgpwbGF0ZV8wMzExMjAyMl9zdW0gPC0KICBwbGF0ZV8wMzExMjAyMl9zdW0gJT4lIG11dGF0ZShyYXRpbyA9IEJMMS5BbWVhbi9ZTDEuQW1lYW4pICU+JQogIGdyb3VwX2J5KGJhY2tncm91bmRfcCwgcmVjZXB0b3JfcCkgJT4lIAogIG11dGF0ZShub3JtYWxpemVkcmF0aW8gPSByYXRpby9tZWFuKHJhdGlvKSkKYGBgCgpgYGB7cn0KcmF0aW8gPC0gCiAgZ2dwbG90KGRhdGEgPSBzdWJzZXQocGxhdGVfMDMxMTIwMjJfc3VtKSwgCiAgICAgICAgIGFlcyh4ID0gdGltZSwgeSA9IG5vcm1hbGl6ZWRyYXRpbywgIAogICAgICAgICAgICAgZ3JvdXAgPSBpbnRlcmFjdGlvbihmYWN0b3IoY29sb255KSwgZmFjdG9yKHRyZWF0bWVudCkpLCAKICAgICAgICAgICAgIGxpbmV0eXBlID0gIGZhY3Rvcih0cmVhdG1lbnQpLCBzaGFwZSA9IGZhY3Rvcih0cmVhdG1lbnQpLCAKICAgICAgICAgICAgIGNvbG9yID0gZmFjdG9yKHRyZWF0bWVudCkpKSArCiAgZ2VvbV9wb2ludChhZXMoY29sb3IgPSB0cmVhdG1lbnQpLCBzaXplID0gMikgKyAKICBnZW9tX2xpbmUoYWVzKGNvbG9yID0gdHJlYXRtZW50KSwgbGluZXdpZHRoPSAxKSAgKyAKICB4bGFiKCJUaW1lIHBvc3QgYXV4aW4gYWRkaXRpb24gKG1pbikiKSArIAogIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXMgPSBjKDE5LCAxKSkgKyAKICB5bGFiKCJOb3JtYWxpemVkIFZlbnVzL21TY2FybGV0LUkiKSArIAogIGZhY2V0X2dyaWQoYmFja2dyb3VuZF9wfnJlY2VwdG9yX3ApICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiIzU0OTlDNyIsICIjOTk5OTk5IikpICsgCiAgdGhlbWVfYmFzZSgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCAKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aCA9IDAuMywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5ldHlwZSA9ICdzb2xpZCcsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3VyID0gIndoaXRlIiksIAogICAgICAgIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiYmxhY2siLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZXdpZHRoID0gMSwgbGluZXR5cGUgPSAic29saWQiKSkgCnJhdGlvCmBgYAoKV2l0aG91dCBub3JtYWxpemF0aW9uCgpgYGB7cn0KcmF0aW9fcmF3IDwtIAogIGdncGxvdChkYXRhID0gc3Vic2V0KHBsYXRlXzAzMTEyMDIyX3N1bSksIAogICAgICAgICBhZXMoeCA9IHRpbWUsIHkgPSByYXRpbywgIAogICAgICAgICAgICAgZ3JvdXAgPSBpbnRlcmFjdGlvbihmYWN0b3IoY29sb255KSwgZmFjdG9yKHRyZWF0bWVudCkpLCAKICAgICAgICAgICAgIGxpbmV0eXBlID0gIGZhY3Rvcih0cmVhdG1lbnQpLCBzaGFwZSA9IGZhY3Rvcih0cmVhdG1lbnQpLCAKICAgICAgICAgICAgIGNvbG9yID0gZmFjdG9yKHRyZWF0bWVudCkpKSArCiAgZ2VvbV9wb2ludChhZXMoY29sb3IgPSB0cmVhdG1lbnQpLCBzaXplID0gMikgKyAKICBnZW9tX2xpbmUoYWVzKGNvbG9yID0gdHJlYXRtZW50KSwgbGluZXdpZHRoPSAxKSAgKyAKICB4bGFiKCJUaW1lIHBvc3QgYXV4aW4gYWRkaXRpb24gKG1pbikiKSArIAogIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXMgPSBjKDE5LCAxKSkgKyAKICB5bGFiKCJWZW51cy9tU2NhcmxldC1JIikgKyAKICBmYWNldF9ncmlkKGJhY2tncm91bmRfcH5yZWNlcHRvcl9wLCBzY2FsZXMgPSAiZnJlZSIpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiIzU0OTlDNyIsICIjOTk5OTk5IikpICsgCiAgdGhlbWVfYmFzZSgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCAKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aCA9IDAuMywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5ldHlwZSA9ICdzb2xpZCcsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3VyID0gIndoaXRlIiksIAogICAgICAgIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiYmxhY2siLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZXdpZHRoID0gMSwgbGluZXR5cGUgPSAic29saWQiKSkgCnJhdGlvX3JhdwpgYGAKCmBgYHtyfQpyYXRpb19yYXcgLyByYXRpbyArIHBsb3RfYW5ub3RhdGlvbih0YWdfbGV2ZWxzID0gIkEiKSAmIHRoZW1lKHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSkKZ2dzYXZlKCJ0Yy1zdHJhaW5zLnBkZiIsIHdpZHRoID0gNSwgaGVpZ2h0ID0gNykKZ2dzYXZlKCJ0Yy1zdHJhaW5zLnBuZyIsIHdpZHRoID0gNSwgaGVpZ2h0ID0gNykKYGBgCgoKYGBge3J9CiNub3JtYWxpemUgZ3JlZW4gYW5kIHJlZCBmbHVvcmVzY2VudCBleHByZXNzaW9uCnBsYXRlXzAzMTEyMDIyX3N1bSA8LQogIHBsYXRlXzAzMTEyMDIyX3N1bSAlPiUgCiAgbXV0YXRlKGdyZWVuID0gQkwxLkFtZWFuKSAlPiUKICBncm91cF9ieShiYWNrZ3JvdW5kX3AsIHJlY2VwdG9yX3ApICU+JSAKICBtdXRhdGUobm9ybWFsaXplZF9HcmVlbmV4cHJlc3Npb24gPSBCTDEuQW1lYW4vbWVhbihCTDEuQW1lYW4pKSAlPiUKICBtdXRhdGUocmVkID0gWUwxLkFtZWFuKSAlPiUKICBtdXRhdGUobm9ybWFsaXplZF9SZWRleHByZXNzaW9uID0gWUwxLkFtZWFuL21lYW4oWUwxLkFtZWFuKSkKCm5vcm1ncmVlbiA8LSBxcGxvdCh4ID0gdGltZSwgeSA9IG5vcm1hbGl6ZWRfR3JlZW5leHByZXNzaW9uLCBkYXRhID0gcGxhdGVfMDMxMTIwMjJfc3VtLCBncm91cCA9IGludGVyYWN0aW9uKGZhY3Rvcihjb2xvbnkpLCBmYWN0b3IodHJlYXRtZW50KSksIGxpbmV0eXBlID0gIGZhY3Rvcih0cmVhdG1lbnQpLCBzaGFwZSA9IGZhY3Rvcih0cmVhdG1lbnQpLCBjb2xvciA9IGZhY3Rvcih0cmVhdG1lbnQpKSArCiAgZ2VvbV9wb2ludChhZXMoY29sb3IgPSB0cmVhdG1lbnQpLCBzaXplID0gMikgKyBnZW9tX2xpbmUoYWVzKGNvbG9yID0gdHJlYXRtZW50KSwgbGluZXdpZHRoID0gMSkgKyB4bGFiKCJUaW1lIHBvc3QgZmlyc3QgcmVhZGluZyAobWluKSIpICsgc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcyA9IGMoMTksIDEpKSArIHlsYWIoIk5vcm1hbGl6ZWQgVmVudXMgZXhwcmVzc2lvbiIpKyBmYWNldF9ncmlkKHJlY2VwdG9yX3B+YmFja2dyb3VuZF9wKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCIjRjFDNDBGIiwgIiM4NTkyOUUiKSkrIHRoZW1lX21pbmltYWwoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGggPSAwLjMsIGxpbmV0eXBlID0gJ3NvbGlkJywgY29sb3VyID0gIndoaXRlIiksIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiYmxhY2siLCBsaW5ld2lkdGggPSAxLCBsaW5ldHlwZSA9ICJzb2xpZCIpKSAKCm5vcm1ncmVlbgoKbm9ybXJlZCA8LXFwbG90KHggPSB0aW1lLCB5ID0gbm9ybWFsaXplZF9SZWRleHByZXNzaW9uLCBkYXRhID0gcGxhdGVfMDMxMTIwMjJfc3VtLCBncm91cCA9IGludGVyYWN0aW9uKGZhY3Rvcihjb2xvbnkpLCBmYWN0b3IodHJlYXRtZW50KSksIGxpbmV0eXBlID0gIGZhY3Rvcih0cmVhdG1lbnQpLCBzaGFwZSA9IGZhY3Rvcih0cmVhdG1lbnQpLCBjb2xvciA9IGZhY3Rvcih0cmVhdG1lbnQpKSArCiAgZ2VvbV9wb2ludChhZXMoY29sb3IgPSB0cmVhdG1lbnQpLCBzaXplID0gMikgKyBnZW9tX2xpbmUoYWVzKGNvbG9yID0gdHJlYXRtZW50KSwgbGluZXdpZHRoID0gMSkgKyB4bGFiKCJUaW1lIHBvc3QgZmlyc3QgcmVhZGluZyAobWluKSIpICsgc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcyA9IGMoMTksIDEpKSArIHlsYWIoIk5vcm1hbGl6ZWQgbVNjYXJsZXQgZXhwcmVzc2lvbiIpKyBmYWNldF9ncmlkKHJlY2VwdG9yX3B+YmFja2dyb3VuZF9wKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCIjRUM3MDYzIiwgIiM2MTZBNkIiKSkgKyB0aGVtZV9taW5pbWFsKCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoID0gMC4zLCBsaW5ldHlwZSA9ICdzb2xpZCcsIGNvbG91ciA9ICJ3aGl0ZSIpLCBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIiwgbGluZXdpZHRoID0gMSwgbGluZXR5cGUgPSAic29saWQiKSkgCm5vcm1yZWQgCgpncmVlbiA8LSBxcGxvdCh4ID0gdGltZSwgeSA9IEJMMS5BbWVhbiwgZGF0YSA9IHBsYXRlXzAzMTEyMDIyX3N1bSwgZ3JvdXAgPSBpbnRlcmFjdGlvbihmYWN0b3IoY29sb255KSwgZmFjdG9yKHRyZWF0bWVudCkpLCBsaW5ldHlwZSA9ICBmYWN0b3IodHJlYXRtZW50KSwgc2hhcGUgPSBmYWN0b3IodHJlYXRtZW50KSwgY29sb3IgPSBmYWN0b3IodHJlYXRtZW50KSkgKwogIGdlb21fcG9pbnQoYWVzKGNvbG9yID0gdHJlYXRtZW50KSwgc2l6ZSA9IDIpICsgZ2VvbV9saW5lKGFlcyhjb2xvciA9IHRyZWF0bWVudCksIGxpbmV3aWR0aCA9IDEpICsgeGxhYigiVGltZSBwb3N0IGZpcnN0IHJlYWRpbmcgKG1pbikiKSArIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXMgPSBjKDE5LCAxKSkgKyB5bGFiKCJOb3JtYWxpemVkIFZlbnVzIGV4cHJlc3Npb24iKSsgZmFjZXRfZ3JpZChyZWNlcHRvcl9wfmJhY2tncm91bmRfcCkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiI0YxQzQwRiIsICIjODU5MjlFIikpKyB0aGVtZV9taW5pbWFsKCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoID0gMC4zLCBsaW5ldHlwZSA9ICdzb2xpZCcsIGNvbG91ciA9ICJ3aGl0ZSIpLCBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIiwgbGluZXdpZHRoID0gMSwgbGluZXR5cGUgPSAic29saWQiKSkgCmdyZWVuCgpyZWQgPC1xcGxvdCh4ID0gdGltZSwgeSA9IFlMMS5BbWVhbiwgZGF0YSA9IHBsYXRlXzAzMTEyMDIyX3N1bSwgZ3JvdXAgPSBpbnRlcmFjdGlvbihmYWN0b3IoY29sb255KSwgZmFjdG9yKHRyZWF0bWVudCkpLCBsaW5ldHlwZSA9ICBmYWN0b3IodHJlYXRtZW50KSwgc2hhcGUgPSBmYWN0b3IodHJlYXRtZW50KSwgY29sb3IgPSBmYWN0b3IodHJlYXRtZW50KSkgKwogIGdlb21fcG9pbnQoYWVzKGNvbG9yID0gdHJlYXRtZW50KSwgc2l6ZSA9IDIpICsgZ2VvbV9saW5lKGFlcyhjb2xvciA9IHRyZWF0bWVudCksIGxpbmV3aWR0aCA9IDEpICsgeGxhYigiVGltZSBwb3N0IGZpcnN0IHJlYWRpbmcgKG1pbikiKSArIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXMgPSBjKDE5LCAxKSkgKyB5bGFiKCJOb3JtYWxpemVkIG1TY2FybGV0IGV4cHJlc3Npb24iKSsgZmFjZXRfZ3JpZChyZWNlcHRvcl9wfmJhY2tncm91bmRfcCkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiI0VDNzA2MyIsICIjNjE2QTZCIikpICsgdGhlbWVfbWluaW1hbCgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aCA9IDAuMywgbGluZXR5cGUgPSAnc29saWQnLCBjb2xvdXIgPSAid2hpdGUiKSwgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJibGFjayIsIGxpbmV3aWR0aCA9IDEsIGxpbmV0eXBlID0gInNvbGlkIikpIApyZWQgCgpjb25jIDwtcXBsb3QoeCA9IHRpbWUsIHkgPSBjb25jLCBkYXRhID0gcGxhdGVfMDMxMTIwMjJfc3VtLCBncm91cCA9IGludGVyYWN0aW9uKGZhY3Rvcihjb2xvbnkpLCBmYWN0b3IodHJlYXRtZW50KSksIGxpbmV0eXBlID0gIGZhY3Rvcih0cmVhdG1lbnQpLCBzaGFwZSA9IGZhY3Rvcih0cmVhdG1lbnQpLCBjb2xvciA9IGZhY3Rvcih0cmVhdG1lbnQpKSArCiAgZ2VvbV9wb2ludChhZXMoY29sb3IgPSB0cmVhdG1lbnQpLCBzaXplID0gMikgKyBnZW9tX2xpbmUoYWVzKGNvbG9yID0gdHJlYXRtZW50KSwgbGluZXdpZHRoID0gMSkgKyB4bGFiKCJUaW1lIHBvc3QgZmlyc3QgcmVhZGluZyAobWluKSIpICsgc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcyA9IGMoMTksIDEpKSArIHlsYWIoIk5vcm1hbGl6ZWQgbVNjYXJsZXQgZXhwcmVzc2lvbiIpKyBmYWNldF9ncmlkKHJlY2VwdG9yX3B+YmFja2dyb3VuZF9wKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJibGFjayIsICIjNjE2QTZCIikpICsgdGhlbWVfbWluaW1hbCgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aCA9IDAuMywgbGluZXR5cGUgPSAnc29saWQnLCBjb2xvdXIgPSAid2hpdGUiKSwgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJibGFjayIsIGxpbmV3aWR0aCA9IDEsIGxpbmV0eXBlID0gInNvbGlkIikpIApjb25jIApgYGAKCiMgQ1YgcGxvdAoKVXNpbmcgdGhlIGFib3ZlIHRpbWUgY291cnNlIGRhdGFzZXQgd2UgY2FuIGNvbXBhcmUgY29lZmZpY2llbnRzIG9mIHZhcmlhdGlvbiBpbiB0aGUgaW5kaXZpZHVhbCBwYXJhbWV0ZXJzIGFuZCB0aGUgcmF0aW8gZm9yIGVhY2ggb2YgdGhlIHN0cmFpbnMgYW5kIGJpb3NlbnNvcnMgYXQgc3RlYWR5IHN0YXRlLgoKIyMgeVdMMTg1IChUSVIxIGR1YWwtZnVzaW9uLCBXMzAzIHllYXN0KQoKYGBge3J9CgpkYXRhMTg1IDwtIHN0ZWFkeVN0YXRlKGFwbGF0ZV8wMzExMjAyMiwgZ2F0ZWQgPSBUUlVFKQpkYXRhMTg1IDwtIHN1YnNldChkYXRhMTg1LCBzdHJhaW4gPT0gInlXTDE4NSIgJiBuYW1lICVpbiUgYygiODAzMTEyMDIyLVBhdC1UQ0EwOF9UaW1lLWNvdXJzZSBhc3NheV9BdXhpbl95V0wxODUtQzEuZmNzIiwgIjgwMzExMjAyMi1QYXQtVENBMDhfVGltZS1jb3Vyc2UgYXNzYXlfQ29udHJvbF95V0wxODUtQzEuZmNzIiApKQoKY3YgPC0gZnVuY3Rpb24oeCkgcmV0dXJuKHJvdW5kKHNkKHgpL21lYW4oeCksMikpCgoKZGF0YTE4NSA8LSBzdWJzZXQoZGF0YTE4NSwgQkwxLkEgPjEgJiBZTDEuQSA+IDEpCmRhdGExODUkRkxyYXRpbyA8LSBkYXRhMTg1JEJMMS5BL2RhdGExODUkWUwxLkEKcmFuZ2UoZGF0YTE4NSRCTDEuQSkKY3YgPC0gZnVuY3Rpb24oeCkgcmV0dXJuKHJvdW5kKHNkKHgpL21lYW4oeCksMikpCgpkYXRhMTg1JFZlbnVzIDwtIGRhdGExODUkQkwxLkEgLyBtZWRpYW4oZGF0YTE4NSRCTDEuQSkKZGF0YTE4NSRtU2NhcmxldCA8LSBkYXRhMTg1JFlMMS5BIC8gbWVkaWFuKGRhdGExODUkWUwxLkEpCmRhdGExODUkRkxyYXRpbyA8LSBkYXRhMTg1JEJMMS5BIC8gZGF0YTE4NSRZTDEuQQpkYXRhMTg1JHJhdGlvIDwtIGRhdGExODUkRkxyYXRpbyAvIG1lZGlhbihkYXRhMTg1JEZMcmF0aW8pCgoKCmRhdGFfbG9uZzE4NSA8LSBkYXRhMTg1ICU+JSAKICBkcGx5cjo6c2VsZWN0KHRyZWF0bWVudCwgVmVudXMsIG1TY2FybGV0LCByYXRpbywgc3RyYWluKSAlPiUKICBwaXZvdF9sb25nZXIoY29scyA9IGMoVmVudXMsIG1TY2FybGV0LCByYXRpbyksIAogICAgICAgICAgICAgICBuYW1lc190byA9ICJwYXJhbWV0ZXIiLCAKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gInZhbHVlIikgJT4lCiAgZHBseXI6Om11dGF0ZShwYXJhbWV0ZXIgPSBmY3RfcmVsZXZlbChwYXJhbWV0ZXIsICJWZW51cyIpKSAKCiMgbmVlZCB0byBhbHNvIGZvcm1hdCBDVnMgYXBwcm9yaWF0ZWx5IGZvciBhbm5vdGF0aW5nCgpDVjE4NSA8LQogIGRhdGExODUgJT4lIGdyb3VwX2J5KHRyZWF0bWVudCkgJT4lIAogIGRwbHlyOjpzdW1tYXJpc2UoYWNyb3NzKGRwbHlyOjp3aGVyZShpc19kb3VibGUpLCBjdikpICU+JQogIGRwbHlyOjpzZWxlY3QodHJlYXRtZW50LCBWZW51cywgbVNjYXJsZXQsIHJhdGlvKSAlPiUKICBwaXZvdF9sb25nZXIoCiAgICBjb2xzID0gYyhWZW51cywgbVNjYXJsZXQsIHJhdGlvKSwKICAgIG5hbWVzX3RvID0gInBhcmFtZXRlciIsCiAgICB2YWx1ZXNfdG8gPSAidmFsdWUiCiAgKQoKI2RhdGExODUKCnBsb3QxODUgPC0gZ2dwbG90KGRhdGEgPSBkYXRhX2xvbmcxODUsIAogICAgICAgbWFwcGluZyA9IGFlcyh4ID0gdmFsdWUsIAogICAgICAgICAgICAgICAgICAgICBjb2xvciA9IHRyZWF0bWVudCkpICsgCiAgZ2VvbV9kZW5zaXR5KCkgKyB4bGltKGMoLTEsNCkpICsgCiAgbGFicyh4ID0gIm1lZGlhbiBub3JtYWxpemVkIGludGVuc2l0eSIsIGNvbG9yID0gInRyZWF0bWVudCIpICArIHRoZW1lX3Rlc3QoKSArIAogIGdlb21fdGV4dChkYXRhID0gc3Vic2V0KENWMTg1LCB0cmVhdG1lbnQgPT0gIjUwIHVNIEF1eGluIiksIAogICAgICAgICAgICAgYWVzKGxhYmVsID0gcGFzdGUwKCJDViA9ICIsIHZhbHVlKSksCiAgICAgICAgICAgICB4ID0gMiwgeSA9IDEpICsgCiAgZ2VvbV90ZXh0KGRhdGEgPSBzdWJzZXQoQ1YxODUsIHRyZWF0bWVudCA9PSAiQ29udHJvbCIpLCAKICAgICAgICAgICAgIGFlcyhsYWJlbCA9IHBhc3RlMCgiQ1YgPSAiLCB2YWx1ZSkpLCAKICAgICAgICAgICAgeCA9IDAsIHkgPSAxKSArIAogIHNjYWxlX2NvbG9yX3ZpcmlkaXNfZChvcHRpb24gPSAiRCIsIGVuZCA9IC43NSwgZGlyZWN0aW9uID0gLTEpIAoKCgoKdmVudXMxODUgPC0gZ2dwbG90KGRhdGExODUsIGFlcyh4PWRhdGExODUkVmVudXMsIGdyb3VwPXRyZWF0bWVudCwgZmlsbD10cmVhdG1lbnQsIGNvbG9yPSB0cmVhdG1lbnQpKSArIGdlb21fZGVuc2l0eShhZGp1c3Q9MS41LCBhbHBoYT0uNSkgKyBsYWJzKHggPSAiVmVudXMiLCB5ID0iRGVuc2l0eSIpICsgeGxpbSgtMC4xLDIpKyB5bGltKDAsMikgKyB0aGVtZV9jbGFzc2ljKCkgKyAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgICsgZ2VvbV90ZXh0KGRhdGEgPSBzdWJzZXQoQ1YxODUsIHBhcmFtZXRlciA9PSAiVmVudXMiICYgdHJlYXRtZW50ID09ICI1MCB1TSBBdXhpbiIpLCBhZXMobGFiZWwgPSBwYXN0ZTAoIkNWID0gIiwgdmFsdWUpKSwKICAgICAgICAgICAgIHggPSAxLjIsIHkgPSAxLjEpICsgCiAgZ2VvbV90ZXh0KGRhdGEgPSBzdWJzZXQoQ1YxODUsIHBhcmFtZXRlciA9PSAiVmVudXMiJiB0cmVhdG1lbnQgPT0gIkNvbnRyb2wiKSwgCiAgICAgICAgICAgICBhZXMobGFiZWwgPSBwYXN0ZTAoIkNWID0gIiwgdmFsdWUpKSwgCiAgICAgICAgICAgIHggPSAwLjU1LCB5ID0gMS41KSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9YygiI0YxQzQwRiIsICIjNjI2NTY3IikpICsgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoIiNGMUM0MEYiLCAiIzYyNjU2NyIpKQojdmVudXMxODUKCnJlZDE4NSA8LSBnZ3Bsb3QoZGF0YTE4NSwgYWVzKHg9ZGF0YTE4NSRtU2NhcmxldCwgZ3JvdXA9dHJlYXRtZW50LCBmaWxsPXRyZWF0bWVudCwgY29sb3I9IHRyZWF0bWVudCkpICsgZ2VvbV9kZW5zaXR5KGFkanVzdD0xLjUsIGFscGhhPS41KSArIGxhYnMoeCA9ICJtU2NhcmxldCIsIHkgPSJEZW5zaXR5IikgKyB4bGltKC0wLjEsMikgKyB5bGltKDAsMikgKyB0aGVtZV9jbGFzc2ljKCkgKyAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgICsgZ2VvbV90ZXh0KGRhdGEgPSBzdWJzZXQoQ1YxODUsIHBhcmFtZXRlciA9PSAibVNjYXJsZXQiICYgdHJlYXRtZW50ID09ICI1MCB1TSBBdXhpbiIpLCBhZXMobGFiZWwgPSBwYXN0ZTAoIkNWID0gIiwgdmFsdWUpKSwKICAgICAgICAgICAgIHggPSAxLjIsIHkgPSAxLjEpICsgCiAgZ2VvbV90ZXh0KGRhdGEgPSBzdWJzZXQoQ1YxODUsIHBhcmFtZXRlciA9PSAibVNjYXJsZXQiJiB0cmVhdG1lbnQgPT0gIkNvbnRyb2wiKSwgCiAgICAgICAgICAgICBhZXMobGFiZWwgPSBwYXN0ZTAoIkNWID0gIiwgdmFsdWUpKSwgCiAgICAgICAgICAgIHggPSAwLjU1LCB5ID0gMS41KSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9YygiI0NCNDMzNSIsICIjNjI2NTY3IikpICsgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoIiNDQjQzMzUiLCAiIzYyNjU2NyIpKQojcmVkMTg1CgoKcmF0aW8xODU8LSBnZ3Bsb3QoZGF0YTE4NSwgYWVzKHg9ZGF0YTE4NSRyYXRpbywgZ3JvdXA9dHJlYXRtZW50LCBmaWxsPXRyZWF0bWVudCwgY29sb3I9IHRyZWF0bWVudCkpICsgZ2VvbV9kZW5zaXR5KGFkanVzdD0xLjUsIGFscGhhPS41KSAgK2xhYnMoeCA9ICJWZW51cy9tU2NhcmxldCByYXRpbyIsIHkgPSJEZW5zaXR5IikgKyB4bGltKC0wLjEsMikgKyB5bGltKDAsMy41KSArIHRoZW1lX2NsYXNzaWMoKSArICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAgICsgIGdlb21fdGV4dChkYXRhID0gc3Vic2V0KENWMTg1LCBwYXJhbWV0ZXIgPT0gInJhdGlvIiAmIHRyZWF0bWVudCA9PSAiNTAgdU0gQXV4aW4iKSwgYWVzKGxhYmVsID0gcGFzdGUwKCJDViA9ICIsIHZhbHVlKSksCiAgICAgICAgICAgICB4ID0gMC40LCB5ID0gMikgKyAKICBnZW9tX3RleHQoZGF0YSA9IHN1YnNldChDVjE4NSwgcGFyYW1ldGVyID09ICJyYXRpbyImIHRyZWF0bWVudCA9PSAiQ29udHJvbCIpLCAKICAgICAgICAgICAgIGFlcyhsYWJlbCA9IHBhc3RlMCgiQ1YgPSAiLCB2YWx1ZSkpLCAKICAgICAgICAgICAgeCA9IDEuNiwgeSA9IDIpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz1jKCIjNTQ5OUM3IiwgIiM2MjY1NjciKSkgKyBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiIzU0OTlDNyIsICIjNjI2NTY3IikpCgojcmF0aW8xODUKCnBsb3QxODUgPC0gZ3JpZC5hcnJhbmdlKHZlbnVzMTg1LCByZWQxODUsIHJhdGlvMTg1LCBucm93PTMsIG5jb2w9MSkKcGxvdDE4NQoKYGBgCgojIyB5V0wxODYgKEFGQjIgZHVhbC1mdXNpb24sIFczMDMgeWVhc3QpCgpgYGB7cn0KZGF0YTE4NiA8LSBzdGVhZHlTdGF0ZShhcGxhdGVfMDMxMTIwMjIsIGdhdGVkID0gVFJVRSkKZGF0YTE4NiA8LSBzdWJzZXQoZGF0YTE4Niwgc3RyYWluID09ICJ5V0wxODYiICYgbmFtZSAlaW4lIGMoIjgwMzExMjAyMi1QYXQtVENBMDhfVGltZS1jb3Vyc2UgYXNzYXlfQXV4aW5feVdMMTg2LUMxLmZjcyIsICI4MDMxMTIwMjItUGF0LVRDQTA4X1RpbWUtY291cnNlIGFzc2F5X0NvbnRyb2xfeVdMMTg2LUMxLmZjcyIgKSkKCmN2IDwtIGZ1bmN0aW9uKHgpIHJldHVybihyb3VuZChzZCh4KS9tZWFuKHgpLDIpKQoKCmRhdGExODYgPC0gc3Vic2V0KGRhdGExODYsIEJMMS5BID4xICYgWUwxLkEgPiAxKQpkYXRhMTg2JEZMcmF0aW8gPC0gZGF0YTE4NiRCTDEuQS9kYXRhMTg2JFlMMS5BCnJhbmdlKGRhdGExODYkQkwxLkEpCmN2IDwtIGZ1bmN0aW9uKHgpIHJldHVybihyb3VuZChzZCh4KS9tZWFuKHgpLDIpKQoKZGF0YTE4NiRWZW51cyA8LSBkYXRhMTg2JEJMMS5BIC8gbWVkaWFuKGRhdGExODYkQkwxLkEpCmRhdGExODYkbVNjYXJsZXQgPC0gZGF0YTE4NiRZTDEuQSAvIG1lZGlhbihkYXRhMTg2JFlMMS5BKQpkYXRhMTg2JEZMcmF0aW8gPC0gZGF0YTE4NiRCTDEuQSAvIGRhdGExODYkWUwxLkEKZGF0YTE4NiRyYXRpbyA8LSBkYXRhMTg2JEZMcmF0aW8gLyBtZWRpYW4oZGF0YTE4NiRGTHJhdGlvKQoKCgpkYXRhX2xvbmcxODYgPC0gZGF0YTE4NiAlPiUgCiAgZHBseXI6OnNlbGVjdCh0cmVhdG1lbnQsIFZlbnVzLCBtU2NhcmxldCwgcmF0aW8sIHN0cmFpbikgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKFZlbnVzLCBtU2NhcmxldCwgcmF0aW8pLCAKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAicGFyYW1ldGVyIiwgCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJ2YWx1ZSIpICU+JQogIGRwbHlyOjptdXRhdGUocGFyYW1ldGVyID0gZmN0X3JlbGV2ZWwocGFyYW1ldGVyLCAiVmVudXMiKSkgCgojIG5lZWQgdG8gYWxzbyBmb3JtYXQgQ1ZzIGFwcHJvcmlhdGVseSBmb3IgYW5ub3RhdGluZwoKQ1YxODYgPC0KICBkYXRhMTg2ICU+JSBncm91cF9ieSh0cmVhdG1lbnQpICU+JSAKICBkcGx5cjo6c3VtbWFyaXNlKGFjcm9zcyhkcGx5cjo6d2hlcmUoaXNfZG91YmxlKSwgY3YpKSAlPiUKICBkcGx5cjo6c2VsZWN0KHRyZWF0bWVudCwgVmVudXMsIG1TY2FybGV0LCByYXRpbykgJT4lCiAgcGl2b3RfbG9uZ2VyKAogICAgY29scyA9IGMoVmVudXMsIG1TY2FybGV0LCByYXRpbyksCiAgICBuYW1lc190byA9ICJwYXJhbWV0ZXIiLAogICAgdmFsdWVzX3RvID0gInZhbHVlIgogICkKCiNkYXRhMTg2CgpwbG90MTg2IDwtIGdncGxvdChkYXRhID0gZGF0YV9sb25nMTg2LCAKICAgICAgIG1hcHBpbmcgPSBhZXMoeCA9IHZhbHVlLCAKICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSB0cmVhdG1lbnQpKSArIAogIGdlb21fZGVuc2l0eSgpICsgeGxpbShjKC0xLDQpKSArIAogIGxhYnMoeCA9ICJtZWRpYW4gbm9ybWFsaXplZCBpbnRlbnNpdHkiLCBjb2xvciA9ICJ0cmVhdG1lbnQiKSAgKyB0aGVtZV90ZXN0KCkgKyAKICBnZW9tX3RleHQoZGF0YSA9IHN1YnNldChDVjE4NiwgdHJlYXRtZW50ID09ICI1MCB1TSBBdXhpbiIpLCAKICAgICAgICAgICAgIGFlcyhsYWJlbCA9IHBhc3RlMCgiQ1YgPSAiLCB2YWx1ZSkpLAogICAgICAgICAgICAgeCA9IDIsIHkgPSAxKSArIAogIGdlb21fdGV4dChkYXRhID0gc3Vic2V0KENWMTg2LCB0cmVhdG1lbnQgPT0gIkNvbnRyb2wiKSwgCiAgICAgICAgICAgICBhZXMobGFiZWwgPSBwYXN0ZTAoIkNWID0gIiwgdmFsdWUpKSwgCiAgICAgICAgICAgIHggPSAwLCB5ID0gMSkgKyAKICBzY2FsZV9jb2xvcl92aXJpZGlzX2Qob3B0aW9uID0gIkQiLCBlbmQgPSAuNzUsIGRpcmVjdGlvbiA9IC0xKSAKCgoKdmVudXMxODYgPC0gZ2dwbG90KGRhdGExODYsIGFlcyh4PWRhdGExODYkVmVudXMsIGdyb3VwPXRyZWF0bWVudCwgZmlsbD10cmVhdG1lbnQsIGNvbG9yID0gdHJlYXRtZW50KSkgKyBnZW9tX2RlbnNpdHkoYWRqdXN0PTEuNSwgYWxwaGE9LjQpICsgbGFicyh4ID0gIlZlbnVzIChub3JtYWxpemVkIG1lZGlhbikiLCB5ID0iRGVuc2l0eSIpICsgeGxpbSgwLDIpKyB5bGltKDAsMikgKyB0aGVtZV9jbGFzc2ljKCkgKyAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgKyBnZW9tX3RleHQoZGF0YSA9IHN1YnNldChDVjE4NiwgcGFyYW1ldGVyID09ICJWZW51cyIgJiB0cmVhdG1lbnQgPT0gIjUwIHVNIEF1eGluIiksIGFlcyhsYWJlbCA9IHBhc3RlMCgiQ1YgPSAiLCB2YWx1ZSkpLAogICAgICAgICAgICAgeCA9IDEuMiwgeSA9IDEuMSkgKyAKICBnZW9tX3RleHQoZGF0YSA9IHN1YnNldChDVjE4NiwgcGFyYW1ldGVyID09ICJWZW51cyImIHRyZWF0bWVudCA9PSAiQ29udHJvbCIpLCAKICAgICAgICAgICAgIGFlcyhsYWJlbCA9IHBhc3RlMCgiQ1YgPSAiLCB2YWx1ZSkpLCAKICAgICAgICAgICAgeCA9IDAuNTUsIHkgPSAxLjUpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz1jKCIjRjFDNDBGIiwgIiM2MjY1NjciKSkgKyBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiI0YxQzQwRiIsICIjNjI2NTY3IikpCgoKcmVkMTg2IDwtIGdncGxvdChkYXRhMTg2LCBhZXMoeD1kYXRhMTg2JG1TY2FybGV0LCBncm91cD10cmVhdG1lbnQsIGZpbGw9dHJlYXRtZW50LCBjb2xvciA9IHRyZWF0bWVudCkpICsgZ2VvbV9kZW5zaXR5KGFkanVzdD0xLjUsIGFscGhhPS40KSArIGxhYnMoeCA9ICJtU2NhcmxldCAobm9ybWFsaXplZCBtZWRpYW4pIiwgeSA9IkRlbnNpdHkiKSArIHhsaW0oMCwyKSArIHlsaW0oMCwyKSArIHRoZW1lX2NsYXNzaWMoKSArICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSArICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiI0VDNzA2MyIsICIjOTk5OTk5IikpICsgZ2VvbV90ZXh0KGRhdGEgPSBzdWJzZXQoQ1YxODYsIHBhcmFtZXRlciA9PSAibVNjYXJsZXQiICYgdHJlYXRtZW50ID09ICI1MCB1TSBBdXhpbiIpLCBhZXMobGFiZWwgPSBwYXN0ZTAoIkNWID0gIiwgdmFsdWUpKSwKICAgICAgICAgICAgIHggPSAxLjIsIHkgPSAxLjEpICsgCiAgZ2VvbV90ZXh0KGRhdGEgPSBzdWJzZXQoQ1YxODYsIHBhcmFtZXRlciA9PSAibVNjYXJsZXQiJiB0cmVhdG1lbnQgPT0gIkNvbnRyb2wiKSwgCiAgICAgICAgICAgICBhZXMobGFiZWwgPSBwYXN0ZTAoIkNWID0gIiwgdmFsdWUpKSwgCiAgICAgICAgICAgIHggPSAwLjU1LCB5ID0gMS41KSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9YygiI0NCNDMzNSIsICIjNjI2NTY3IikpICsgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoIiNDQjQzMzUiLCAiIzYyNjU2NyIpKQoKCnJhdGlvMTg2PC0gZ2dwbG90KGRhdGExODYsIGFlcyh4PWRhdGExODYkcmF0aW8sIGdyb3VwPXRyZWF0bWVudCwgZmlsbD10cmVhdG1lbnQsIGNvbG9yID0gdHJlYXRtZW50KSkgKyBnZW9tX2RlbnNpdHkoYWRqdXN0PTEuNSwgYWxwaGE9LjQpICArbGFicyh4ID0gIlZlbnVzL21TY2FybGV0IHJhdGlvIiwgeSA9IkRlbnNpdHkiKSArIHhsaW0oMCwyKSArIHlsaW0oMCwzLjUpICsgdGhlbWVfY2xhc3NpYygpICsgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpICAgKyAgZ2VvbV90ZXh0KGRhdGEgPSBzdWJzZXQoQ1YxODYsIHBhcmFtZXRlciA9PSAicmF0aW8iICYgdHJlYXRtZW50ID09ICI1MCB1TSBBdXhpbiIpLCBhZXMobGFiZWwgPSBwYXN0ZTAoIkNWID0gIiwgdmFsdWUpKSwKICAgICAgICAgICAgIHggPSAwLjIsIHkgPSAyKSArIAogIGdlb21fdGV4dChkYXRhID0gc3Vic2V0KENWMTg2LCBwYXJhbWV0ZXIgPT0gInJhdGlvIiYgdHJlYXRtZW50ID09ICJDb250cm9sIiksIAogICAgICAgICAgICAgYWVzKGxhYmVsID0gcGFzdGUwKCJDViA9ICIsIHZhbHVlKSksIAogICAgICAgICAgICB4ID0gMS4zLCB5ID0gMikgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoIiM1NDk5QzciLCAiIzYyNjU2NyIpKSArIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCIjNTQ5OUM3IiwgIiM2MjY1NjciKSkKCnBsb3QxODYgPC0gZ3JpZC5hcnJhbmdlKHZlbnVzMTg2LCByZWQxODYsIHJhdGlvMTg2LCBucm93PTMsIG5jb2w9MSkKcGxvdDE4NgpgYGAKCiMjIHlXTDIwOSAoVElSMSBkdWFsLWZ1c2lvbiwgWVBINDk5IHllYXN0KQoKYGBge3J9CgpkYXRhMjA5IDwtIHN0ZWFkeVN0YXRlKGFwbGF0ZV8wMzExMjAyMiwgZ2F0ZWQgPSBUUlVFKQpkYXRhMjA5IDwtIHN1YnNldChkYXRhMjA5LCBzdHJhaW4gPT0gInlXTDIwOSIgJiBuYW1lICVpbiUgYygiODAzMTEyMDIyLVBhdC1UQ0EwOF9UaW1lLWNvdXJzZSBhc3NheV9BdXhpbl95V0wyMDktQzEuZmNzIiwgIjgwMzExMjAyMi1QYXQtVENBMDhfVGltZS1jb3Vyc2UgYXNzYXlfQ29udHJvbF95V0wyMDktQzEuZmNzIiApKQoKY3YgPC0gZnVuY3Rpb24oeCkgcmV0dXJuKHJvdW5kKHNkKHgpL21lYW4oeCksMikpCgoKZGF0YTIwOSA8LSBzdWJzZXQoZGF0YTIwOSwgQkwxLkEgPjEgJiBZTDEuQSA+IDEpCmRhdGEyMDkkRkxyYXRpbyA8LSBkYXRhMjA5JEJMMS5BL2RhdGEyMDkkWUwxLkEKcmFuZ2UoZGF0YTIwOSRCTDEuQSkKY3YgPC0gZnVuY3Rpb24oeCkgcmV0dXJuKHJvdW5kKHNkKHgpL21lYW4oeCksMikpCgpkYXRhMjA5JFZlbnVzIDwtIGRhdGEyMDkkQkwxLkEgLyBtZWRpYW4oZGF0YTIwOSRCTDEuQSkKZGF0YTIwOSRtU2NhcmxldCA8LSBkYXRhMjA5JFlMMS5BIC8gbWVkaWFuKGRhdGEyMDkkWUwxLkEpCmRhdGEyMDkkRkxyYXRpbyA8LSBkYXRhMjA5JEJMMS5BIC8gZGF0YTIwOSRZTDEuQQpkYXRhMjA5JHJhdGlvIDwtIGRhdGEyMDkkRkxyYXRpbyAvIG1lZGlhbihkYXRhMjA5JEZMcmF0aW8pCgoKCmRhdGFfbG9uZzIwOSA8LSBkYXRhMjA5ICU+JSAKICBkcGx5cjo6c2VsZWN0KHRyZWF0bWVudCwgVmVudXMsIG1TY2FybGV0LCByYXRpbywgc3RyYWluKSAlPiUKICBwaXZvdF9sb25nZXIoY29scyA9IGMoVmVudXMsIG1TY2FybGV0LCByYXRpbyksIAogICAgICAgICAgICAgICBuYW1lc190byA9ICJwYXJhbWV0ZXIiLCAKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gInZhbHVlIikgJT4lCiAgZHBseXI6Om11dGF0ZShwYXJhbWV0ZXIgPSBmY3RfcmVsZXZlbChwYXJhbWV0ZXIsICJWZW51cyIpKSAKCiMgbmVlZCB0byBhbHNvIGZvcm1hdCBDVnMgYXBwcm9yaWF0ZWx5IGZvciBhbm5vdGF0aW5nCgpDVjIwOSA8LQogIGRhdGEyMDkgJT4lIGdyb3VwX2J5KHRyZWF0bWVudCkgJT4lIAogIGRwbHlyOjpzdW1tYXJpc2UoYWNyb3NzKGRwbHlyOjp3aGVyZShpc19kb3VibGUpLCBjdikpICU+JQogIGRwbHlyOjpzZWxlY3QodHJlYXRtZW50LCBWZW51cywgbVNjYXJsZXQsIHJhdGlvKSAlPiUKICBwaXZvdF9sb25nZXIoCiAgICBjb2xzID0gYyhWZW51cywgbVNjYXJsZXQsIHJhdGlvKSwKICAgIG5hbWVzX3RvID0gInBhcmFtZXRlciIsCiAgICB2YWx1ZXNfdG8gPSAidmFsdWUiCiAgKQoKI2RhdGEyMDkKCnBsb3QyMDkgPC0gZ2dwbG90KGRhdGEgPSBkYXRhX2xvbmcyMDksIAogICAgICAgbWFwcGluZyA9IGFlcyh4ID0gdmFsdWUsIAogICAgICAgICAgICAgICAgICAgICBjb2xvciA9IHRyZWF0bWVudCkpICsgCiAgZ2VvbV9kZW5zaXR5KCkgKyB4bGltKGMoLTEsNCkpICsgCiAgbGFicyh4ID0gIm1lZGlhbiBub3JtYWxpemVkIGludGVuc2l0eSIsIGNvbG9yID0gInRyZWF0bWVudCIpICArIHRoZW1lX3Rlc3QoKSArIAogIGdlb21fdGV4dChkYXRhID0gc3Vic2V0KENWMjA5LCB0cmVhdG1lbnQgPT0gIjUwIHVNIEF1eGluIiksIAogICAgICAgICAgICAgYWVzKGxhYmVsID0gcGFzdGUwKCJDViA9ICIsIHZhbHVlKSksCiAgICAgICAgICAgICB4ID0gMS4yLCB5ID0gMSkgKyAKICBnZW9tX3RleHQoZGF0YSA9IHN1YnNldChDVjIwOSwgdHJlYXRtZW50ID09ICJDb250cm9sIiksIAogICAgICAgICAgICAgYWVzKGxhYmVsID0gcGFzdGUwKCJDViA9ICIsIHZhbHVlKSksIAogICAgICAgICAgICB4ID0gMCwgeSA9IDEpICsgCiAgc2NhbGVfY29sb3JfdmlyaWRpc19kKG9wdGlvbiA9ICJEIiwgZW5kID0gLjc1LCBkaXJlY3Rpb24gPSAtMSkgCgoKCgp2ZW51czIwOSA8LSBnZ3Bsb3QoZGF0YTIwOSwgYWVzKHg9ZGF0YTIwOSRWZW51cywgZ3JvdXA9dHJlYXRtZW50LCBmaWxsPXRyZWF0bWVudCwgY29sb3IgPSB0cmVhdG1lbnQpKSArIGdlb21fZGVuc2l0eShhZGp1c3Q9MS41LCBhbHBoYT0uNCkgKyBsYWJzKHggPSAiVmVudXMiLCB5ID0iRGVuc2l0eSIpICsgeGxpbSgwLDIpKyB5bGltKDAsMikgKyB0aGVtZV9jbGFzc2ljKCkgKyAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgICsgZ2VvbV90ZXh0KGRhdGEgPSBzdWJzZXQoQ1YyMDksIHBhcmFtZXRlciA9PSAiVmVudXMiICYgdHJlYXRtZW50ID09ICI1MCB1TSBBdXhpbiIpLCBhZXMobGFiZWwgPSBwYXN0ZTAoIkNWID0gIiwgdmFsdWUpKSwKICAgICAgICAgICAgIHggPSAxLjIsIHkgPSAxLjEpICsgCiAgZ2VvbV90ZXh0KGRhdGEgPSBzdWJzZXQoQ1YyMDksIHBhcmFtZXRlciA9PSAiVmVudXMiJiB0cmVhdG1lbnQgPT0gIkNvbnRyb2wiKSwgCiAgICAgICAgICAgICBhZXMobGFiZWwgPSBwYXN0ZTAoIkNWID0gIiwgdmFsdWUpKSwgCiAgICAgICAgICAgIHggPSAwLjU1LCB5ID0gMS41KSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9YygiI0YxQzQwRiIsICIjNjI2NTY3IikpICsgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoIiNGMUM0MEYiLCAiIzYyNjU2NyIpKQoKCnJlZDIwOSA8LSBnZ3Bsb3QoZGF0YTIwOSwgYWVzKHg9ZGF0YTIwOSRtU2NhcmxldCwgZ3JvdXA9dHJlYXRtZW50LCBmaWxsPXRyZWF0bWVudCwgY29sb3IgPSB0cmVhdG1lbnQpKSArIGdlb21fZGVuc2l0eShhZGp1c3Q9MS41LCBhbHBoYT0uNCkgKyBsYWJzKHggPSAibVNjYXJsZXQiLCB5ID0iRGVuc2l0eSIpICsgeGxpbSgwLDIpICsgeWxpbSgwLDIpICsgdGhlbWVfY2xhc3NpYygpICsgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpICArIGdlb21fdGV4dChkYXRhID0gc3Vic2V0KENWMjA5LCBwYXJhbWV0ZXIgPT0gIm1TY2FybGV0IiAmIHRyZWF0bWVudCA9PSAiNTAgdU0gQXV4aW4iKSwgYWVzKGxhYmVsID0gcGFzdGUwKCJDViA9ICIsIHZhbHVlKSksCiAgICAgICAgICAgICB4ID0gMS4yLCB5ID0gMS4xKSArIAogIGdlb21fdGV4dChkYXRhID0gc3Vic2V0KENWMjA5LCBwYXJhbWV0ZXIgPT0gIm1TY2FybGV0IiYgdHJlYXRtZW50ID09ICJDb250cm9sIiksIAogICAgICAgICAgICAgYWVzKGxhYmVsID0gcGFzdGUwKCJDViA9ICIsIHZhbHVlKSksIAogICAgICAgICAgICB4ID0gMC41NSwgeSA9IDEuNSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoIiNDQjQzMzUiLCAiIzYyNjU2NyIpKSArIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCIjQ0I0MzM1IiwgIiM2MjY1NjciKSkKCgpyYXRpbzIwOTwtIGdncGxvdChkYXRhMjA5LCBhZXMoeD1kYXRhMjA5JHJhdGlvLCBncm91cD10cmVhdG1lbnQsIGZpbGw9dHJlYXRtZW50LCBjb2xvciA9IHRyZWF0bWVudCkpICsgZ2VvbV9kZW5zaXR5KGFkanVzdD0xLjUsIGFscGhhPS40KSAgK2xhYnMoeCA9ICJWZW51cy9tU2NhcmxldCByYXRpbyIsIHkgPSJEZW5zaXR5IikgKyB4bGltKDAsMikgKyB5bGltKDAsMy41KSArIHRoZW1lX2NsYXNzaWMoKSArICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAgICsgIGdlb21fdGV4dChkYXRhID0gc3Vic2V0KENWMjA5LCBwYXJhbWV0ZXIgPT0gInJhdGlvIiAmIHRyZWF0bWVudCA9PSAiNTAgdU0gQXV4aW4iKSwgYWVzKGxhYmVsID0gcGFzdGUwKCJDViA9ICIsIHZhbHVlKSksCiAgICAgICAgICAgICB4ID0gMC4zLCB5ID0gMikgKyAKICBnZW9tX3RleHQoZGF0YSA9IHN1YnNldChDVjIwOSwgcGFyYW1ldGVyID09ICJyYXRpbyImIHRyZWF0bWVudCA9PSAiQ29udHJvbCIpLCAKICAgICAgICAgICAgIGFlcyhsYWJlbCA9IHBhc3RlMCgiQ1YgPSAiLCB2YWx1ZSkpLCAKICAgICAgICAgICAgeCA9IDEuNiwgeSA9IDIpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz1jKCIjNTQ5OUM3IiwgIiM2MjY1NjciKSkgKyBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiIzU0OTlDNyIsICIjNjI2NTY3IikpCgoKcGxvdDIwOSA8LSBncmlkLmFycmFuZ2UodmVudXMyMDksIHJlZDIwOSwgcmF0aW8yMDksIG5yb3c9MywgbmNvbD0xKQpwbG90MjA5CgoKYGBgCgoKIyMgeVdMMjEwIChBRkIyIGR1YWwtZnVzaW9uLCBZUEg0OTkgeWVhc3QpCgpgYGB7cn0KCmRhdGEyMTAgPC0gc3RlYWR5U3RhdGUoYXBsYXRlXzAzMTEyMDIyLCBnYXRlZCA9IFRSVUUpCiNkYXRhIDwtIHRpZHlGbG93KGFwbGF0ZV8yMDIxMDYxOV9XMzAzKQoKZGF0YTIxMCA8LSBzdWJzZXQoZGF0YTIxMCwgc3RyYWluID09ICJ5V0wyMTAiICYgbmFtZSAlaW4lIGMoIjgwMzExMjAyMi1QYXQtVENBMDhfVGltZS1jb3Vyc2UgYXNzYXlfQXV4aW5feVdMMjEwLUMxLmZjcyIsICI4MDMxMTIwMjItUGF0LVRDQTA4X1RpbWUtY291cnNlIGFzc2F5X0NvbnRyb2xfeVdMMjEwLUMxLmZjcyIgKSkKCmN2IDwtIGZ1bmN0aW9uKHgpIHJldHVybihyb3VuZChzZCh4KS9tZWFuKHgpLDIpKQoKCmRhdGEyMTAgPC0gc3Vic2V0KGRhdGEyMTAsIEJMMS5BID4xICYgWUwxLkEgPiAxKQpkYXRhMjEwJEZMcmF0aW8gPC0gZGF0YTIxMCRCTDEuQS9kYXRhMjEwJFlMMS5BCnJhbmdlKGRhdGEyMTAkQkwxLkEpCmN2IDwtIGZ1bmN0aW9uKHgpIHJldHVybihyb3VuZChzZCh4KS9tZWFuKHgpLDIpKQoKZGF0YTIxMCRWZW51cyA8LSBkYXRhMjEwJEJMMS5BIC8gbWVkaWFuKGRhdGEyMTAkQkwxLkEpCmRhdGEyMTAkbVNjYXJsZXQgPC0gZGF0YTIxMCRZTDEuQSAvIG1lZGlhbihkYXRhMjEwJFlMMS5BKQpkYXRhMjEwJEZMcmF0aW8gPC0gZGF0YTIxMCRCTDEuQSAvIGRhdGEyMTAkWUwxLkEKZGF0YTIxMCRyYXRpbyA8LSBkYXRhMjEwJEZMcmF0aW8gLyBtZWRpYW4oZGF0YTIxMCRGTHJhdGlvKQoKCgpkYXRhX2xvbmcyMTAgPC0gZGF0YTIxMCAlPiUgCiAgZHBseXI6OnNlbGVjdCh0cmVhdG1lbnQsIFZlbnVzLCBtU2NhcmxldCwgcmF0aW8sIHN0cmFpbikgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKFZlbnVzLCBtU2NhcmxldCwgcmF0aW8pLCAKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAicGFyYW1ldGVyIiwgCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJ2YWx1ZSIpICU+JQogIGRwbHlyOjptdXRhdGUocGFyYW1ldGVyID0gZmN0X3JlbGV2ZWwocGFyYW1ldGVyLCAiVmVudXMiKSkgCgojIG5lZWQgdG8gYWxzbyBmb3JtYXQgQ1ZzIGFwcHJvcmlhdGVseSBmb3IgYW5ub3RhdGluZwoKQ1YyMTAgPC0KICBkYXRhMjEwICU+JSBncm91cF9ieSh0cmVhdG1lbnQpICU+JSAKICBkcGx5cjo6c3VtbWFyaXNlKGFjcm9zcyhkcGx5cjo6d2hlcmUoaXNfZG91YmxlKSwgY3YpKSAlPiUKICBkcGx5cjo6c2VsZWN0KHRyZWF0bWVudCwgVmVudXMsIG1TY2FybGV0LCByYXRpbykgJT4lCiAgcGl2b3RfbG9uZ2VyKAogICAgY29scyA9IGMoVmVudXMsIG1TY2FybGV0LCByYXRpbyksCiAgICBuYW1lc190byA9ICJwYXJhbWV0ZXIiLAogICAgdmFsdWVzX3RvID0gInZhbHVlIgogICkKCiNkYXRhMjEwCgpwbG90MjEwIDwtIGdncGxvdChkYXRhID0gZGF0YV9sb25nMjEwLCAKICAgICAgIG1hcHBpbmcgPSBhZXMoeCA9IHZhbHVlLCAKICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSB0cmVhdG1lbnQpKSArIAogIGdlb21fZGVuc2l0eSgpICsgeGxpbShjKC0xLDQpKSArIAogIGxhYnMoeCA9ICJtZWRpYW4gbm9ybWFsaXplZCBpbnRlbnNpdHkiLCBjb2xvciA9ICJ0cmVhdG1lbnQiKSAgKyB0aGVtZV90ZXN0KCkgKyAKICBnZW9tX3RleHQoZGF0YSA9IHN1YnNldChDVjIxMCwgdHJlYXRtZW50ID09ICI1MCB1TSBBdXhpbiIpLCAKICAgICAgICAgICAgIGFlcyhsYWJlbCA9IHBhc3RlMCgiQ1YgPSAiLCB2YWx1ZSkpLAogICAgICAgICAgICAgeCA9IDIsIHkgPSAxKSArIAogIGdlb21fdGV4dChkYXRhID0gc3Vic2V0KENWMjEwLCB0cmVhdG1lbnQgPT0gIkNvbnRyb2wiKSwgCiAgICAgICAgICAgICBhZXMobGFiZWwgPSBwYXN0ZTAoIkNWID0gIiwgdmFsdWUpKSwgCiAgICAgICAgICAgIHggPSAwLCB5ID0gMSkgKyAKICBzY2FsZV9jb2xvcl92aXJpZGlzX2Qob3B0aW9uID0gIkQiLCBlbmQgPSAuNzUsIGRpcmVjdGlvbiA9IC0xKSArCiAgZmFjZXRfZ3JpZChwYXJhbWV0ZXJ+LikgCgoKCgp2ZW51czIxMCA8LSBnZ3Bsb3QoZGF0YTIxMCwgYWVzKHg9ZGF0YTIxMCRWZW51cywgZ3JvdXA9dHJlYXRtZW50LGNvbG9yPXRyZWF0bWVudCwgIGZpbGw9dHJlYXRtZW50KSkgKyBnZW9tX2RlbnNpdHkoYWRqdXN0PTEuNSwgYWxwaGE9LjQpICsgbGFicyh4ID0gIlZlbnVzIiwgeSA9IkRlbnNpdHkiKSArIHhsaW0oMCwyKSsgeWxpbSgwLDIpICsgdGhlbWVfY2xhc3NpYygpICsgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpICsgIGdlb21fdGV4dChkYXRhID0gc3Vic2V0KENWMjEwLCBwYXJhbWV0ZXIgPT0gIlZlbnVzIiAmIHRyZWF0bWVudCA9PSAiNTAgdU0gQXV4aW4iKSwgYWVzKGxhYmVsID0gcGFzdGUwKCJDViA9ICIsIHZhbHVlKSksCiAgICAgICAgICAgICB4ID0gMS41LCB5ID0gMSkgKyAKICBnZW9tX3RleHQoZGF0YSA9IHN1YnNldChDVjIxMCwgcGFyYW1ldGVyID09ICJWZW51cyImIHRyZWF0bWVudCA9PSAiQ29udHJvbCIpLCAKICAgICAgICAgICAgIGFlcyhsYWJlbCA9IHBhc3RlMCgiQ1YgPSAiLCB2YWx1ZSkpLCAKICAgICAgICAgICAgeCA9IDAuNywgeSA9IDEuNSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoIiNGMUM0MEYiLCAiIzYyNjU2NyIpKSArIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCIjRjFDNDBGIiwgIiM2MjY1NjciKSkKCgpyZWQyMTAgPC0gZ2dwbG90KGRhdGEyMTAsIGFlcyh4PWRhdGEyMTAkbVNjYXJsZXQsIGdyb3VwPXRyZWF0bWVudCxjb2xvcj10cmVhdG1lbnQsICBmaWxsPXRyZWF0bWVudCkpICsgZ2VvbV9kZW5zaXR5KGFkanVzdD0xLjUsIGFscGhhPS40KSArIGxhYnMoeCA9ICJtU2NhcmxldCIsIHkgPSJEZW5zaXR5IikgKyB4bGltKDAsMikgKyB5bGltKDAsMikgKyB0aGVtZV9jbGFzc2ljKCkgKyAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgKyBnZW9tX3RleHQoZGF0YSA9IHN1YnNldChDVjIxMCwgcGFyYW1ldGVyID09ICJtU2NhcmxldCIgJiB0cmVhdG1lbnQgPT0gIjUwIHVNIEF1eGluIiksIGFlcyhsYWJlbCA9IHBhc3RlMCgiQ1YgPSAiLCB2YWx1ZSkpLAogICAgICAgICAgICAgeCA9IDEuMiwgeSA9IDEuMikgKyAKICBnZW9tX3RleHQoZGF0YSA9IHN1YnNldChDVjIxMCwgcGFyYW1ldGVyID09ICJtU2NhcmxldCImIHRyZWF0bWVudCA9PSAiQ29udHJvbCIpLCAKICAgICAgICAgICAgIGFlcyhsYWJlbCA9IHBhc3RlMCgiQ1YgPSAiLCB2YWx1ZSkpLCAKICAgICAgICAgICAgeCA9IDAuNCwgeSA9IDEuNSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoIiNDQjQzMzUiLCAiIzYyNjU2NyIpKSArIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCIjQ0I0MzM1IiwgIiM2MjY1NjciKSkKCgpyYXRpbzIxMDwtIGdncGxvdChkYXRhMjEwLCBhZXMoeD1kYXRhMjEwJHJhdGlvLCBncm91cD10cmVhdG1lbnQsIGNvbG9yPXRyZWF0bWVudCwgZmlsbCA9IHRyZWF0bWVudCkpICsgZ2VvbV9kZW5zaXR5KGFkanVzdD0xLjUsIGFscGhhPS40KSAgK2xhYnMoeCA9ICJWZW51cy9tU2NhcmxldCByYXRpbyIsIHkgPSJEZW5zaXR5IikgKyB4bGltKDAsMikgKyB5bGltKDAsMy41KSArIHRoZW1lX2NsYXNzaWMoKSArICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSAgKyBnZW9tX3RleHQoZGF0YSA9IHN1YnNldChDVjIxMCwgcGFyYW1ldGVyID09ICJyYXRpbyIgJiB0cmVhdG1lbnQgPT0gIjUwIHVNIEF1eGluIiksIGFlcyhsYWJlbCA9IHBhc3RlMCgiQ1YgPSAiLCB2YWx1ZSkpLAogICAgICAgICAgICAgeCA9IDAuMiwgeSA9IDEuOCkgKyAKICBnZW9tX3RleHQoZGF0YSA9IHN1YnNldChDVjIxMCwgcGFyYW1ldGVyID09ICJyYXRpbyImIHRyZWF0bWVudCA9PSAiQ29udHJvbCIpLCAKICAgICAgICAgICAgIGFlcyhsYWJlbCA9IHBhc3RlMCgiQ1YgPSAiLCB2YWx1ZSkpLCAKICAgICAgICAgICAgeCA9IDEuNiwgeSA9IDEuOCkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoIiM1NDk5QzciLCAiIzYyNjU2NyIpKSArIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCIjNTQ5OUM3IiwgIiM2MjY1NjciKSkKI3JhdGlvMjEwCgpwbG90MjEwIDwtIGdyaWQuYXJyYW5nZSh2ZW51czIxMCwgcmVkMjEwLCByYXRpbzIxMCwgbnJvdz0zLCBuY29sPTEpCnBsb3QyMTAKCmBgYAoKYGBge3J9CmR1YWxfZnVzaW9uX2N2IDwtICh2ZW51czIxMCArIGdndGl0bGUoIkFGQjIiKSsgCiAgICAgICAgICAgICAgICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkgfCAKICAgICAgICAgICAgICAgIHZlbnVzMjA5ICsgZ2d0aXRsZSgiVElSMSIpICsgCiAgICAgICAgICAgICAgICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkpIC8gCiAgICAgICAgICAgICAgIChyZWQyMTAgfCByZWQyMDkpIC8gCiAgICAgICAgICAgICAocmF0aW8yMTAgfCByYXRpbzIwOSkgKyAKICB0aGVtZSh0aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDApKQpkdWFsX2Z1c2lvbl9jdiAKZ2dzYXZlKCJkdWFsX2Z1c2lvbl9jdi5wZGYiLCB3aWR0aCA9IDYuMywgaGVpZ2h0ID0gNikKZ2dzYXZlKCJkdWFsX2Z1c2lvbl9jdi5wbmciLCB3aWR0aCA9IDYuMywgaGVpZ2h0ID0gNikKYGBgCgojIFNpbmdsZS1mdXNpb24gdnMgZHVhbC1mdXNpb24gY29tcGFyaXNvbiBpbiBXMzAzIHllYXN0IHN0cmFpbgoKLSAgIHlXTDE2MSAoVElSMSBzaW5nbGUtZnVzaW9uLCBXMzAzIHllYXN0KQotICAgeVdMMTYyIChBRkIyIHNpbmdsZS1mdXNpb24sIFczMDMgeWVhc3QpCi0gICB5V0wxODUgKFRJUjEgZHVhbC1mdXNpb24sIFczMDMgeWVhc3QpCi0gICB5V0wxODYgKEFGQjIgZHVhbC1mdXNpb24sIFczMDMgeWVhc3QpCgpgYGB7ciwgZXZhbD1GQUxTRX0KcGxhdGVfMjAyMTA2MTlfVzMwMyA8LSByZWFkLnBsYXRlU2V0KHBhdGggPSAifi9Hb29nbGUgRHJpdmUvU2hhcmVkIGRyaXZlcy9QbGFudFN5bkJpb0xhYi9QYXQvRXhwZXJpbWVudHMvVGltZSBjb3Vyc2UgYXNzYXlzLzIwMjEwNjE5L1czMDNvbmx5LyIsIHBhdHRlcm4gPSAicioiKSAKYGBgCgpgYGB7ciwgZXZhbCA9IEZ9CmFubm90YXRpb24gPC0gY3JlYXRlQW5ub3RhdGlvbih5b3VyRmxvd1NldCA9IHBsYXRlXzIwMjEwNjE5X1czMDMpCndyaXRlLmNzdihhbm5vdGF0aW9uLCcvVXNlcnMvcGF0Y2hhaXN1cGEvR29vZ2xlIERyaXZlL1NoYXJlZCBkcml2ZXMvUGxhbnRTeW5CaW9MYWIvUGF0L0V4cGVyaW1lbnRzL1RpbWUgY291cnNlIGFzc2F5cy8yMDIxMDYxOS8yMDIxMDYxOV9XMzAzb25seV9hbm5vdGF0aW9uLmNzdicpCmBgYAoKYGBge3IsIGV2YWw9RkFMU0V9CmFubm90YXRpb24gPC0gcmVhZC5jc3YoJ34vR29vZ2xlIERyaXZlL1NoYXJlZCBkcml2ZXMvUGxhbnRTeW5CaW9MYWIvUGF0L0V4cGVyaW1lbnRzL1RpbWUgY291cnNlIGFzc2F5cy8yMDIxMDYxOS8yMDIxMDYxOV9XMzAzb25seV9hbm5vdGF0aW9uLmNzdicpCmFwbGF0ZV8yMDIxMDYxOV9XMzAzIDwtIGFubm90YXRlRmxvd1NldCh5b3VyRmxvd1NldCA9IHBsYXRlXzIwMjEwNjE5X1czMDMsIGFubm90YXRpb25fZGYgPSBhbm5vdGF0aW9uLCBtZXJnZUJ5ID0gJ25hbWUnKQpoZWFkKHJvd25hbWVzKHBEYXRhKGFwbGF0ZV8yMDIxMDYxOV9XMzAzKSkpCmhlYWQocERhdGEoYXBsYXRlXzIwMjEwNjE5X1czMDMpKQp3cml0ZS5mbG93U2V0KGFwbGF0ZV8yMDIxMDYxOV9XMzAzLCBvdXRkaXIgPSAiZmxvd1NldHMvZGVzaWduLXJlbGF0aXZlLWV4cHJlc3Npb24iKQpgYGAKCmBgYHtyfQphcGxhdGVfMjAyMTA2MTlfVzMwMyA8LSByZWFkLmZsb3dTZXQocGF0aCA9ICJmbG93U2V0cy9kZXNpZ24tcmVsYXRpdmUtZXhwcmVzc2lvbi8iLCBwaGVub0RhdGEgPSAiYW5ub3RhdGlvbi50eHQiKQpwbGF0ZV8yMDIxMDYxOV9XMzAzX3N1bSA8LSBzdW1tYXJpemVGbG93KGFwbGF0ZV8yMDIxMDYxOV9XMzAzLCAgZ2F0ZWQgPSBUUlVFKQoKCiNUaGUgdGltZSBhdXhpbiBhZGRpdGlvbiBpcyBlcXVhbCB0byB0aW1lIHplcm8KdGltZTAgPC0gIjRFMDEuZmNzIiAKIyBvciB3aGF0ZXZlciB3ZWxsIHdhcyBiZWluZyByZWFkIHdoZW4gYXV4aW4gd2FzIGFkZGVkCgpwbGF0ZV8yMDIxMDYxOV9XMzAzX3N1bSR0aW1lIDwtIHBsYXRlXzIwMjEwNjE5X1czMDNfc3VtJGJ0aW1lLXBsYXRlXzIwMjEwNjE5X1czMDNfc3VtW1t3aGljaChwbGF0ZV8yMDIxMDYxOV9XMzAzX3N1bSRuYW1lID09IHRpbWUwKSwgImJ0aW1lIl1dCiNzaW5nbGUgYnJhY2tldCAtLT5leHRyYWN0aW5nIHRoZSBhbGwgbmFtZSwgMiBicmFja2V0cyBleHRyYWN0IGp1c3Qgc2luZ2xlICJ2YWx1ZSIgb3IgInZhbHVlcyIKCmBgYAoKYGBge3J9CnBsYXRlXzIwMjEwNjE5X1czMDNfc3VtIDwtIHBsYXRlXzIwMjEwNjE5X1czMDNfc3VtICU+JQogIG11dGF0ZSgKICAgIGRlc2lnbiA9IGNhc2Vfd2hlbigKICAgICAgc3RyYWluICVpbiUgYygieVdMMTg1IiwieVdMMTg2IikgfiAiZHVhbC1mdXNpb24iLAogICAgc3RyYWluICVpbiUgYygieVdMMTYxIiwieVdMMTYyIikgfiAic2luZ2xlLWZ1c2lvbiIpLCAKICAgICAgICAgZmJveCA9IGNhc2Vfd2hlbigKICAgIHN0cmFpbiAlaW4lIGMoInlXTDE2MSIsInlXTDE4NSIpIH4gIlRJUjEiLAogICAgc3RyYWluICVpbiUgYygieVdMMTYyIiwieVdMMTg2IikgfiAiQUZCMiIpKSAlPiUKICBtdXRhdGUoZGVzaWduX2NvbnN0cnVjdCA9IHBhc3RlKGZib3gsIGRlc2lnbikpIAoKcGxhdGVfMjAyMTA2MTlfVzMwM19zdW0gPC0KICBwbGF0ZV8yMDIxMDYxOV9XMzAzX3N1bSAlPiUgbXV0YXRlKHJhdGlvID0gRkwxLkFtZWFuL0ZMNC5BbWVhbikgJT4lCiAgZ3JvdXBfYnkoZGVzaWduLCBmYm94KSAlPiUgCiAgbXV0YXRlKG5vcm1hbGl6ZWRyYXRpbyA9IHJhdGlvL21lYW4ocmF0aW8pKQoKcGxhdGVfMjAyMTA2MTlfVzMwM19zdW08LQogIHBsYXRlXzIwMjEwNjE5X1czMDNfc3VtICU+JSBtdXRhdGUoZ3JlZW4gPSBGTDEuQW1lYW4pICU+JQogIGdyb3VwX2J5KGRlc2lnbiwgZmJveCkgJT4lIAogIG11dGF0ZShub3JtYWxpemVkX0dyZWVuZXhwcmVzc2lvbiA9IEZMMS5BbWVhbi9tZWFuKEZMMS5BbWVhbikpCgpwbGF0ZV8yMDIxMDYxOV9XMzAzX3N1bSA8LQogIHBsYXRlXzIwMjEwNjE5X1czMDNfc3VtICU+JSBtdXRhdGUocmVkID0gRkw0LkFtZWFuKSAlPiUKICBncm91cF9ieShkZXNpZ24sIGZib3gpICU+JSAKICBtdXRhdGUobm9ybWFsaXplZF9SZWRleHByZXNzaW9uID0gRkw0LkFtZWFuL21lYW4oRkw0LkFtZWFuKSkKYGBgCgpgYGB7cn0KVElSMV9zaW5nbGUgPC0gcXBsb3QoeCA9IHRpbWUsIHkgPSBGTDEuQW1lYW4vRkw0LkFtZWFuLCBkYXRhID0gc3Vic2V0KHBsYXRlXzIwMjEwNjE5X1czMDNfc3VtLCBzdHJhaW4gPT0ieVdMMTYxIiksIGdyb3VwID0gZmFjdG9yKHRyZWF0bWVudCksIGxpbmV0eXBlID0gIGZhY3Rvcih0cmVhdG1lbnQpLCBzaGFwZSA9IGZhY3Rvcih0cmVhdG1lbnQpLCBjb2xvciA9IGZhY3Rvcih0cmVhdG1lbnQpKSArCiAgeGxhYigiVGltZSAobWluKSIpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvciA9IHRyZWF0bWVudCwgc2hhcGUgPSB0cmVhdG1lbnQpLCBzaXplID0gMSkgKyBnZW9tX2xpbmUoYWVzKGNvbG9yID0gdHJlYXRtZW50LCBzaGFwZSA9IHRyZWF0bWVudCksIGxpbmV3aWR0aCA9IDAuNSkgICsgIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXMgPSBjKDE5LCAxKSkgKyB5bGFiKCJWZW51cy9TY2FybGV0IHJhdGlvIikgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiIzU0OTlDNyIsICIjNjI2NTY3IikpICsgdGhlbWVfbWluaW1hbCgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aCA9IDAuMywgbGluZXR5cGUgPSAnc29saWQnLCBjb2xvdXIgPSAid2hpdGUiKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGggPSAwLjMsIGxpbmV0eXBlID0gJ3NvbGlkJywgY29sb3VyID0gIndoaXRlIikpICtmYWNldF93cmFwKH5kZXNpZ25fY29uc3RydWN0LCBzY2FsZSA9ImZyZWVfeSIpIAoKCkFGQjJfc2luZ2xlIDwtIHFwbG90KHggPSB0aW1lLCB5ID0gRkwxLkFtZWFuL0ZMNC5BbWVhbiwgZGF0YSA9IHN1YnNldChwbGF0ZV8yMDIxMDYxOV9XMzAzX3N1bSwgc3RyYWluID09InlXTDE2MiIpLCBncm91cCA9IGZhY3Rvcih0cmVhdG1lbnQpLCBsaW5ldHlwZSA9ICBmYWN0b3IodHJlYXRtZW50KSwgc2hhcGUgPSBmYWN0b3IodHJlYXRtZW50KSwgY29sb3IgPSBmYWN0b3IodHJlYXRtZW50KSkgKwogICB4bGFiKCJUaW1lIChtaW4pIikgKwogIGdlb21fcG9pbnQoYWVzKGNvbG9yID0gdHJlYXRtZW50LCBzaGFwZSA9IHRyZWF0bWVudCksIHNpemUgPSAxKSArIGdlb21fbGluZShhZXMoY29sb3IgPSB0cmVhdG1lbnQsIHNoYXBlID0gdHJlYXRtZW50KSwgbGluZXdpZHRoID0gMC41KSAgKyBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gYygxOSwgMSkpICsgeWxhYigiVmVudXMvU2NhcmxldCByYXRpbyIpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoIiM1NDk5QzciLCAiIzYyNjU2NyIpKSArIHRoZW1lX21pbmltYWwoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoID0gMC4zLCBsaW5ldHlwZSA9ICdzb2xpZCcsIGNvbG91ciA9ICJ3aGl0ZSIpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aCA9IDAuMywgbGluZXR5cGUgPSAnc29saWQnLCBjb2xvdXIgPSAid2hpdGUiKSkgK2ZhY2V0X3dyYXAofmRlc2lnbl9jb25zdHJ1Y3QsIHNjYWxlID0iZnJlZV95IikgCgpUSVIxX2R1YWwgPC0gcXBsb3QoeCA9IHRpbWUsIHkgPSBGTDEuQW1lYW4vRkw0LkFtZWFuLCBkYXRhID0gc3Vic2V0KHBsYXRlXzIwMjEwNjE5X1czMDNfc3VtLCBzdHJhaW4gPT0ieVdMMTg1IiksIGdyb3VwID0gZmFjdG9yKHRyZWF0bWVudCksIGxpbmV0eXBlID0gIGZhY3Rvcih0cmVhdG1lbnQpLCBzaGFwZSA9IGZhY3Rvcih0cmVhdG1lbnQpLCBjb2xvciA9IGZhY3Rvcih0cmVhdG1lbnQpKSArCiAgZ2VvbV9wb2ludChhZXMoY29sb3IgPSB0cmVhdG1lbnQsIHNoYXBlID0gdHJlYXRtZW50KSwgc2l6ZSA9IDEpICsgZ2VvbV9saW5lKGFlcyhjb2xvciA9IHRyZWF0bWVudCwgc2hhcGUgPSB0cmVhdG1lbnQpLCBsaW5ld2lkdGggPSAwLjUpICArIHhsYWIoIlRpbWUgKG1pbikiKSArIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXMgPSBjKDE5LCAxKSkgKyB5bGFiKCJWZW51cy9TY2FybGV0IHJhdGlvIikgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiIzU0OTlDNyIsICIjNjI2NTY3IikpICsgdGhlbWVfbWluaW1hbCgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aCA9IDAuMywgbGluZXR5cGUgPSAnc29saWQnLCBjb2xvdXIgPSAid2hpdGUiKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGggPSAwLjMsIGxpbmV0eXBlID0gJ3NvbGlkJywgY29sb3VyID0gIndoaXRlIikpICtmYWNldF93cmFwKH5kZXNpZ25fY29uc3RydWN0LCBzY2FsZSA9ImZyZWVfeSIpIAoKQUZCMl9kdWFsIDwtIHFwbG90KHggPSB0aW1lLCB5ID0gRkwxLkFtZWFuL0ZMNC5BbWVhbiwgZGF0YSA9IHN1YnNldChwbGF0ZV8yMDIxMDYxOV9XMzAzX3N1bSwgc3RyYWluID09InlXTDE4NiIpLCBncm91cCA9IGZhY3Rvcih0cmVhdG1lbnQpLCBsaW5ldHlwZSA9ICBmYWN0b3IodHJlYXRtZW50KSwgc2hhcGUgPSBmYWN0b3IodHJlYXRtZW50KSwgY29sb3IgPSBmYWN0b3IodHJlYXRtZW50KSkgKwogICB4bGFiKCJUaW1lIChtaW4pIikgKwogIGdlb21fcG9pbnQoYWVzKGNvbG9yID0gdHJlYXRtZW50LCBzaGFwZSA9IHRyZWF0bWVudCksIHNpemUgPSAxKSArIGdlb21fbGluZShhZXMoY29sb3IgPSB0cmVhdG1lbnQsIHNoYXBlID0gdHJlYXRtZW50KSwgbGluZXdpZHRoID0gMC41KSAgKyBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gYygxOSwgMSkpICsgeWxhYigiVmVudXMvU2NhcmxldCByYXRpbyIpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoIiM1NDk5QzciLCAiIzYyNjU2NyIpKSArIHRoZW1lX21pbmltYWwoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGggPSAwLjMsIGxpbmV0eXBlID0gJ3NvbGlkJywgY29sb3VyID0gIndoaXRlIiksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoID0gMC4zLCBsaW5ldHlwZSA9ICdzb2xpZCcsIGNvbG91ciA9ICJ3aGl0ZSIpKSArZmFjZXRfd3JhcCh+ZGVzaWduX2NvbnN0cnVjdCwgc2NhbGUgPSJmcmVlX3kiKSAKCmdyaWQuYXJyYW5nZShBRkIyX3NpbmdsZSwgVElSMV9zaW5nbGUsIFRJUjFfZHVhbCwgQUZCMl9kdWFsLCBucm93PTIsIG5jb2w9NCkKYGBgCgpgYGB7cn0KVzMwM3JhdGlvIDwtIHFwbG90KHggPSB0aW1lLCB5ID0gbm9ybWFsaXplZHJhdGlvLCBkYXRhID0gc3Vic2V0KHBsYXRlXzIwMjEwNjE5X1czMDNfc3VtKSwgZ3JvdXAgPSBmYWN0b3IodHJlYXRtZW50KSwgbGluZXR5cGUgPSAgZmFjdG9yKHRyZWF0bWVudCksIHNoYXBlID0gZmFjdG9yKHRyZWF0bWVudCksIGNvbG9yID0gZmFjdG9yKHRyZWF0bWVudCkpICsgeGxhYigiVGltZSAobWluKSIpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvciA9IHRyZWF0bWVudCksIHNpemUgPSAwLjUpICsgZ2VvbV9saW5lKGFlcyhjb2xvciA9IHRyZWF0bWVudCksIGxpbmV3aWR0aCA9IDEpICArICBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gYygxOSwgMSkpICsgeWxhYigiVmVudXMiKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCIjMkU4NkMxIiwgIiM2MjY1NjciKSkgICsgdGhlbWVfbWluaW1hbCgpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKGxpbmV3aWR0aCA9IDAuMywgbGluZXR5cGUgPSAnc29saWQnLCBjb2xvdXIgPSAid2hpdGUiKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGggPSAwLjMsIGxpbmV0eXBlID0gJ3NvbGlkJywgY29sb3VyID0gIndoaXRlIiksIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiYmxhY2siLCAKICAgICAgICAgICAgICAgICAgICAgIGxpbmV3aWR0aCA9IDEsIGxpbmV0eXBlID0gInNvbGlkIikpICsgZmFjZXRfd3JhcCh+ZGVzaWduX2NvbnN0cnVjdCwgc2NhbGUgPSJmcmVlX3kiKQoKVzMwM3ZlbnVzIDwtIHFwbG90KHggPSB0aW1lLCB5ID0gbm9ybWFsaXplZF9HcmVlbmV4cHJlc3Npb24sIGRhdGEgPSBzdWJzZXQocGxhdGVfMjAyMTA2MTlfVzMwM19zdW0pLCBncm91cCA9IGZhY3Rvcih0cmVhdG1lbnQpLCBsaW5ldHlwZSA9ICBmYWN0b3IodHJlYXRtZW50KSwgc2hhcGUgPSBmYWN0b3IodHJlYXRtZW50KSwgY29sb3IgPSBmYWN0b3IodHJlYXRtZW50KSkgKyB4bGFiKCJUaW1lIChtaW4pIikgKwogIGdlb21fcG9pbnQoYWVzKGNvbG9yID0gdHJlYXRtZW50KSwgc2l6ZSA9IDAuNSkgKyBnZW9tX2xpbmUoYWVzKGNvbG9yID0gdHJlYXRtZW50KSwgbGluZXdpZHRoID0gMSkgICsgIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXMgPSBjKDE5LCAxKSkgKyB5bGFiKCJWZW51cy9TY2FybGV0IikgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiI0YxQzQwRiIsICIjNjI2NTY3IikpICArIHRoZW1lX21pbmltYWwoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLCAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShsaW5ld2lkdGggPSAwLjMsIGxpbmV0eXBlID0gJ3NvbGlkJywgY29sb3VyID0gIndoaXRlIiksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUobGluZXdpZHRoID0gMC4zLCBsaW5ldHlwZSA9ICdzb2xpZCcsIGNvbG91ciA9ICJ3aGl0ZSIpLCBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIiwgCiAgICAgICAgICAgICAgICAgICAgICBsaW5ld2lkdGggPSAxLCBsaW5ldHlwZSA9ICJzb2xpZCIpKSArIGZhY2V0X3dyYXAofmRlc2lnbl9jb25zdHJ1Y3QsIHNjYWxlID0iZnJlZV95IikKCmdyaWQuYXJyYW5nZShXMzAzdmVudXMsIFczMDNyYXRpbywgbnJvdz0yLCBuY29sPTIpCgpgYGAKCmBgYHtyfQpWZW51c19hb3YgPC0gYW92KEZMMS5BbWVhbiB+IGRlc2lnbl9jb25zdHJ1Y3QgKiB0cmVhdG1lbnQgKiBiZWZvcmVfYWZ0ZXIsIAogIGRhdGEgPSBwbGF0ZV8yMDIxMDYxOV9XMzAzX3N1bSAlPiUKICBkcGx5cjo6ZmlsdGVyKHRpbWUgPD0gMCB8IHRpbWUgPj0gMjAwKSkKc3VtbWFyeShWZW51c19hb3YpCihWZW51c19IU0QudGVzdCA8LSAKICAgIGFncmljb2xhZTo6SFNELnRlc3QoVmVudXNfYW92LCAKICAgICAgICAgICAgICAgICAgICAgICAgdHJ0ID0gYygiZGVzaWduX2NvbnN0cnVjdCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0cmVhdG1lbnQiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYmVmb3JlX2FmdGVyIiksIAogICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlID0gVFJVRSkpClZlbnVzX2dyb3VwcyA8LSBWZW51c19IU0QudGVzdCRncm91cHMgJT4lIAogIGFzX3RpYmJsZShyb3duYW1lcyA9ICJuYW1lcyIpICU+JQogIHNlcGFyYXRlKGNvbCA9IG5hbWVzLCBpbnRvID0gYygiZGVzaWduX2NvbnN0cnVjdCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0cmVhdG1lbnQiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYmVmb3JlX2FmdGVyIiksIAogICAgICAgICAgIHNlcCA9ICJcXDoiLCByZW1vdmUgPSBGQUxTRSkgJT4lIAogIGxlZnRfam9pbihWZW51c19IU0QudGVzdCRtZWFucyAlPiUgCiAgICAgICAgICAgICAgYXNfdGliYmxlKHJvd25hbWVzID0gIm5hbWVzIikgJT4lIAogICAgICAgICAgICAgIGRwbHlyOjpzZWxlY3QoYyhuYW1lcywgTWF4KSksIAogICAgICAgICAgICBieSA9ICJuYW1lcyIpICU+JQogIG11dGF0ZSh0cmVhdG1lbnQgPSBmY3RfcmV2KHRyZWF0bWVudCksIAogICAgICAgICBiZWZvcmVfYWZ0ZXIgPSBmY3RfcmV2KGJlZm9yZV9hZnRlcikpCgpgYGAKCmBgYHtyfQptU2NhcmxldF9hb3YgPC0gYW92KEZMNC5BbWVhbiB+IGRlc2lnbl9jb25zdHJ1Y3QgKiB0cmVhdG1lbnQgKiBiZWZvcmVfYWZ0ZXIsIAogIGRhdGEgPSBwbGF0ZV8yMDIxMDYxOV9XMzAzX3N1bSAlPiUKICBkcGx5cjo6ZmlsdGVyKHRpbWUgPD0gMCB8IHRpbWUgPj0gMjAwKSkKc3VtbWFyeShtU2NhcmxldF9hb3YpCihtU2NhcmxldF9IU0QudGVzdCA8LSAKICAgIGFncmljb2xhZTo6SFNELnRlc3QobVNjYXJsZXRfYW92LCAKICAgICAgICAgICAgICAgICAgICAgICAgdHJ0ID0gYygiZGVzaWduX2NvbnN0cnVjdCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0cmVhdG1lbnQiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYmVmb3JlX2FmdGVyIiksIAogICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlID0gVFJVRSkpCm1TY2FybGV0X2dyb3VwcyA8LSBtU2NhcmxldF9IU0QudGVzdCRncm91cHMgJT4lIAogIGFzX3RpYmJsZShyb3duYW1lcyA9ICJuYW1lcyIpICU+JQogIHNlcGFyYXRlKGNvbCA9IG5hbWVzLCBpbnRvID0gYygiZGVzaWduX2NvbnN0cnVjdCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0cmVhdG1lbnQiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYmVmb3JlX2FmdGVyIiksIAogICAgICAgICAgIHNlcCA9ICJcXDoiLCByZW1vdmUgPSBGQUxTRSkgJT4lIAogIGxlZnRfam9pbihtU2NhcmxldF9IU0QudGVzdCRtZWFucyAlPiUgCiAgICAgICAgICAgICAgYXNfdGliYmxlKHJvd25hbWVzID0gIm5hbWVzIikgJT4lIAogICAgICAgICAgICAgIGRwbHlyOjpzZWxlY3QoYyhuYW1lcywgTWF4KSksIAogICAgICAgICAgICBieSA9ICJuYW1lcyIpICU+JQogIG11dGF0ZSh0cmVhdG1lbnQgPSBmY3RfcmV2KHRyZWF0bWVudCksIAogICAgICAgICBiZWZvcmVfYWZ0ZXIgPSBmY3RfcmV2KGJlZm9yZV9hZnRlcikpCgpgYGAKCmBgYHtyfQpib3h2ZW51cyA8LSAKICBwbGF0ZV8yMDIxMDYxOV9XMzAzX3N1bSAlPiUKICBkcGx5cjo6ZmlsdGVyKHRpbWUgPD0gMCB8IHRpbWUgPj0gMjAwKSAlPiUKICBnZ3Bsb3QoYWVzKAogICAgICAgICAgIHggPSBmY3RfcmV2KGJlZm9yZV9hZnRlciksCiAgICAgICAgICAgeSA9IEZMMS5BbWVhbi8xMDAwLAogICAgICAgICApKSArCiAgZ2VvbV9ib3hwbG90KAogICAgYWVzKGZpbGwgPSBmY3RfcmV2KHRyZWF0bWVudCkpLCBhbHBoYSA9IDAuNywKICAgIG91dGxpZXIuc2hhcGUgPSBOQSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvciA9IGZjdF9yZXYodHJlYXRtZW50KSksCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlMih3aWR0aCA9IC41NSksIAogICAgICAgICAgICAgc2l6ZSA9IDEpICsKICBnZW9tX3RleHQoZGF0YSA9IFZlbnVzX2dyb3VwcywgCiAgICAgICAgICAgIG1hcHBpbmcgPSBhZXMoeSA9IDEuMDUqTWF4LzEwMDAsIGxhYmVsID0gZ3JvdXBzKSwgCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlMih3aWR0aCA9IDEpLAogICAgICAgICAgICBjb2xvciA9ICJibGFjayIpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiIzhmOGY4ZiIsICIjZWRjMjE1IikpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiIzhmOGY4ZiIsICIjZWRjMjE1IikpICsKICB5bGFiKCJWZW51cyIpICsgCiAgeGxhYigiNTAgwrVNIEF1eGluIHRyZWF0bWVudCIpICsgIAogIGZhY2V0X3dyYXAoIH4gZmJveCwgc2NhbGUgPSAiZnJlZV95IikgKyAKICBmYWNldF9ncmlkKCB+IGRlc2lnbl9jb25zdHJ1Y3QpICsgCiAgdGhlbWVfY2xhc3NpYygpICsgbGFicyhjb2xvciA9ICIiKSAKCgpib3htU2NhcmxldCA8LQogIHBsYXRlXzIwMjEwNjE5X1czMDNfc3VtICU+JQogIGRwbHlyOjpmaWx0ZXIodGltZSA8PSAwIHwgdGltZSA+PSAyMDApICU+JQogIGdncGxvdChhZXMoCiAgICAgICAgICAgeCA9IGZjdF9yZXYoYmVmb3JlX2FmdGVyKSwKICAgICAgICAgICB5ID0gRkw0LkFtZWFuLzEwMDAKICAgICAgICAgKSkgKwogIGdlb21fYm94cGxvdChhZXMoZmlsbCA9IGZjdF9yZXYodHJlYXRtZW50KSksIGFscGhhID0gLjcsCiAgICAgICAgICAgICAgIG91dGxpZXIuc2hhcGUgPSBOQSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvciA9IGZjdF9yZXYodHJlYXRtZW50KSksCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlMih3aWR0aCA9IC41NSksIAogICAgICAgICAgICAgc2l6ZSA9IDEpICsKICAgZ2VvbV90ZXh0KGRhdGEgPSBtU2NhcmxldF9ncm91cHMsIAogICAgICAgICAgICBtYXBwaW5nID0gYWVzKHkgPSAxLjIqTWF4LzEwMDAsIGxhYmVsID0gZ3JvdXBzKSwgCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlMih3aWR0aCA9IDEpLAogICAgICAgICAgICBjb2xvciA9ICJibGFjayIpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiIzhmOGY4ZiIsICIjRUM3MDYzIikpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiIzhmOGY4ZiIsICIjRUM3MDYzIikpICsKICB5bGFiKCJtU2NhcmxldC1JIikgKyAKICB4bGFiKCI1MCDCtU0gQXV4aW4gdHJlYXRtZW50IikgKyAgIAogIGZhY2V0X3dyYXAoIH4gZmJveCwgc2NhbGUgPSAiZnJlZV95IikgKyAKICBmYWNldF9ncmlkKCB+IGRlc2lnbl9jb25zdHJ1Y3QsIHNjYWxlcyA9ICJmcmVlX3kiKSArCiAgdGhlbWVfY2xhc3NpYygpICsgbGFicyhjb2xvciA9ICIiKSArIHNjYWxlX3lfbG9nMTAoKQoKCmd1aWRlX2FyZWEoKSAvIGJveHZlbnVzIC8gYm94bVNjYXJsZXQgKyAKICBwbG90X2Fubm90YXRpb24odGFnX2xldmVscyA9ICJBIikgKyAKICBwbG90X2xheW91dChndWlkZXMgPSAiY29sbGVjdCIsIGhlaWdodHMgPSBjKC4zLCAxLDEpKSAmIAogIHRoZW1lKGxlZ2VuZC5ib3ggPSAiaG9yaXpvbnRhbCIsIAogICAgICAgIGxlZ2VuZC5zcGFjaW5nID0gdW5pdCgwLCAicHQiKSwgCiAgICAgICAgbGVnZW5kLmp1c3RpZmljYXRpb24gPSAidG9wIiwgCiAgICAgICAgbGVnZW5kLm1hcmdpbiA9IG1hcmdpbigpLCAKICAgICAgICBsZWdlbmQuYm94LnNwYWNpbmcgPSB1bml0KDAsICJwdCIpLCAKICAgICAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksIAogICAgICAgIGxlZ2VuZC5rZXkgPSBlbGVtZW50X2JsYW5rKCkpCgpnZ3NhdmUoInJlbGF0aXZlLWV4cHJlc3Npb24tYm94LnBkZiIsIHdpZHRoID0gNiwgaGVpZ2h0ID0gNSkKZ2dzYXZlKCJyZWxhdGl2ZS1leHByZXNzaW9uLWJveC5wbmciLCB3aWR0aCA9IDYsIGhlaWdodCA9IDUpCmBgYAoKYGBge3J9CgoKYGBgCgoKYGBge3J9CnBsYXRlXzIwMjEwNjE5X3JlYWQzYW5kMTIgPC0gcmVhZC5mbG93U2V0KHBhdGggPSAifi9Hb29nbGUgRHJpdmUvU2hhcmVkIGRyaXZlcy9QbGFudFN5bkJpb0xhYi9QYXQvRXhwZXJpbWVudHMvVGltZSBjb3Vyc2UgYXNzYXlzLzIwMjEwNjE5L1czMDNvbmx5X3JlYWQzYW5kMTIvIiwgYWx0ZXIubmFtZXMgPSBUUlVFKSAKYGBgCgpgYGB7ciwgZXZhbCA9IEZ9CmFubm90YXRpb24gPC0gY3JlYXRlQW5ub3RhdGlvbih5b3VyRmxvd1NldCA9IHBsYXRlXzIwMjEwNjE5X3JlYWQzYW5kMTIpCndyaXRlLmNzdihhbm5vdGF0aW9uLCcvVXNlcnMvcGF0Y2hhaXN1cGEvR29vZ2xlIERyaXZlL1NoYXJlZCBkcml2ZXMvUGxhbnRTeW5CaW9MYWIvUGF0L0V4cGVyaW1lbnRzL1RpbWUgY291cnNlIGFzc2F5cy8yMDIxMDYxOS8yMDIxMDYxOV9XMzAzb25seV9yZWFkM2FuZDEyX2Fubm90YXRpb24uY3N2JykKYGBgCgpgYGB7cn0KYW5ub3RhdGlvbiA8LSByZWFkLmNzdignfi9Hb29nbGUgRHJpdmUvU2hhcmVkIGRyaXZlcy9QbGFudFN5bkJpb0xhYi9QYXQvRXhwZXJpbWVudHMvVGltZSBjb3Vyc2UgYXNzYXlzLzIwMjEwNjE5LzIwMjEwNjE5X1czMDNvbmx5X3JlYWQzYW5kMTJfYW5ub3RhdGlvbi5jc3YnKQphcGxhdGVfMjAyMTA2MTlfcmVhZDNhbmQxMjwtIGFubm90YXRlRmxvd1NldCh5b3VyRmxvd1NldCA9IHBsYXRlXzIwMjEwNjE5X3JlYWQzYW5kMTIsIGFubm90YXRpb25fZGYgPSBhbm5vdGF0aW9uLCBtZXJnZUJ5ID0gJ25hbWUnKQpoZWFkKHJvd25hbWVzKHBEYXRhKGFwbGF0ZV8yMDIxMDYxOV9yZWFkM2FuZDEyKSkpCmhlYWQocERhdGEoYXBsYXRlXzIwMjEwNjE5X3JlYWQzYW5kMTIpKQoKYGBgCgpgYGB7cn0KVzMwM19yZWFkM2FuZDEyIDwtIHN1bW1hcml6ZUZsb3coYXBsYXRlXzIwMjEwNjE5X3JlYWQzYW5kMTIsICBnYXRlZCA9IFRSVUUpClczMDNfcmVhZDNhbmQxMiA8LSBXMzAzX3JlYWQzYW5kMTIgJT4lIAogIG11dGF0ZShkZXNpZ24gPSBzdHJfZXh0cmFjdChkZXNpZ25fY29uc3RydWN0LCAiKD88PVxccykuKiIpKSAlPiUKICBtdXRhdGUoZGVzaWduID0gc3RyX2V4dHJhY3QoZGVzaWduX2NvbnN0cnVjdCwgIi4qKD89XFxzKSIpKSAKCnZlbnVzM2FuZDEyX3Vubm9ybSA8LSAKICBnZ3Bsb3QoVzMwM19yZWFkM2FuZDEyLCAKICAgICAgICAgYWVzKHg9ZGVzaWduX2NvbnN0cnVjdCwgCiAgICAgICAgICAgICB5PUZMMS5BbWVhbiwgCiAgICAgICAgICAgICBhbHBoYSA9IGZjdF9yZXYoYmVmb3JlX2FmdGVyKSwgCiAgICAgICAgICAgICBncm91cD10cmVhdG1lbnQpKSArCiAgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gZmFjdG9yKHRyZWF0bWVudCksIAogICAgICAgICAgICAgICAgIHNoYXBlID0gZmFjdG9yKHRyZWF0bWVudCkpLCBzaXplID0gMiwKICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25faml0dGVyZG9kZ2UoCiAgICAgICAgICAgICAgIGRvZGdlLndpZHRoID0gMC43LCAKICAgICAgICAgICAgICAgaml0dGVyLndpZHRoID0gMC41KSkgKyAKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoIiNGMUM0MEYiLCAiIzVGNkE2QSIpKSArCiAgeWxhYigiVmVudXMiKSArIHRoZW1lX2NsYXNzaWMoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NDUsIGhqdXN0ID0gMSkpICsgCiAgc2NhbGVfYWxwaGFfbWFudWFsKHZhbHVlcyA9IGMoMC4zLCAwLjgpKQoKbVNjYXJsZXQzYW5kMTJfdW5ub3JtICA8LSAKICBnZ3Bsb3QoVzMwM19yZWFkM2FuZDEyLCAKICAgICAgICAgYWVzKHg9ZGVzaWduX2NvbnN0cnVjdCwgCiAgICAgICAgICAgICB5PUZMNC5BbWVhbiwgCiAgICAgICAgICAgICBhbHBoYSA9IGZjdF9yZXYoYmVmb3JlX2FmdGVyKSwgCiAgICAgICAgICAgICBncm91cD10cmVhdG1lbnQpKSArCiAgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gZmFjdG9yKHRyZWF0bWVudCksIAogICAgICAgICAgICAgICAgIHNoYXBlID0gZmFjdG9yKHRyZWF0bWVudCkpLCAKICAgICAgICAgICAgIHNpemUgPSAyLCAKICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25faml0dGVyZG9kZ2UoCiAgICAgICAgICAgICAgIGRvZGdlLndpZHRoID0gLjcsIAogICAgICAgICAgICAgICBqaXR0ZXIud2lkdGggPS41KSkgKyAKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoIiNFNzRDM0MiLCAiIzVGNkE2QSIpKSArCiAgeWxhYigibVNjYXJsZXQtSSIpICsgdGhlbWVfY2xhc3NpYygpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NDUsIGhqdXN0ID0gMSkpICsgCiAgc2NhbGVfYWxwaGFfbWFudWFsKHZhbHVlcyA9IGMoMC4zLCAwLjgpKQoKZ3VpZGVfYXJlYSgpIC8gKHZlbnVzM2FuZDEyX3Vubm9ybSB8IG1TY2FybGV0M2FuZDEyX3Vubm9ybSkgKyAKICBwbG90X2xheW91dChndWlkZXMgPSAiY29sbGVjdCIsIAogICAgICAgICAgICAgIGhlaWdodHMgPSBjKDEsIDMpKSAgKwogIHBsb3RfYW5ub3RhdGlvbih0YWdfbGV2ZWxzID0gIkEiKSAmCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSd0b3AnLCBsZWdlbmQuZGlyZWN0aW9uID0gInZlcnRpY2FsIiwKICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksIAogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgbGVnZW5kLmp1c3RpZmljYXRpb24gPSAibGVmdCIsIAogICAgICAgIGxlZ2VuZC5ib3guanVzdCA9ICJsZWZ0IiwgCiAgICAgICAgbGVnZW5kLm1hcmdpbiA9IG1hcmdpbigpKQpnZ3NhdmUoInJlbGF0aXZlLWV4cHJlc3Npb24ucG5nIiwgd2lkdGggPSA0LCBoZWlnaHQgPSAzKQpnZ3NhdmUoInJlbGF0aXZlLWV4cHJlc3Npb24ucGRmIiwgd2lkdGggPSA0LCBoZWlnaHQgPSAzKQpgYGAKCkNvZWZmaWNpZW50IG9mIHZhcmlhdGlvbiAoQ1YpIGFuYWx5c2lzCgpgYGB7cn0KCmRhdGEgPC0gc3RlYWR5U3RhdGUoYXBsYXRlXzIwMjEwNjE5X1czMDMsIGdhdGVkID0gVFJVRSkKI2RhdGEgPC0gdGlkeUZsb3coYXBsYXRlXzIwMjEwNjE5X1czMDMpCgpkYXRhIDwtIHN1YnNldChkYXRhLCBzdHJhaW4gPT0gInlXTDE2MSIgJiBuYW1lICVpbiUgYygiMTFMMDEuZmNzIiwgIjExTDA3LmZjcyIpKQoKI3JhbmdlKGRhdGEkRkwxLkEpCiNzZChkYXRhJEZMcmF0aW8pL21lYW4oZGF0YSRGTHJhdGlvKQojcmFuZ2UoZGF0YSRGTHJhdGlvKQpkYXRhIDwtIHN1YnNldChkYXRhLCBGTDEuQSA+MSAmIEZMNC5BID4gMSkKZGF0YSRGTHJhdGlvIDwtIGRhdGEkRkwxLkEvZGF0YSRGTDQuQQpyYW5nZShkYXRhJEZMMS5BKQojY2FsY3VsYXRlIGN2cwpzZChkYXRhJEZMcmF0aW8pL21lYW4oZGF0YSRGTHJhdGlvKQpyYW5nZShkYXRhJEZMcmF0aW8pCmN2IDwtIGZ1bmN0aW9uKHgpIHJldHVybihyb3VuZChzZCh4KS9tZWFuKHgpLDIpKQoKI2NhbGN1bGF0ZSBub3JtYWxpemVkIHZhbHVlcwpkYXRhJFZlbnVzIDwtIGRhdGEkRkwxLkEgLyBtZWRpYW4oZGF0YSRGTDEuQSkKZGF0YSRtU2NhcmxldCA8LSBkYXRhJEZMNC5BIC8gbWVkaWFuKGRhdGEkRkw0LkEpCmRhdGEkcmF0aW8gPC0gZGF0YSRGTHJhdGlvIC8gbWVkaWFuKGRhdGEkRkxyYXRpbykKQ1ZzIDwtIGRhdGEgJT4lIGdyb3VwX2J5KHRyZWF0bWVudCkgJT4lCiAgc3VtbWFyaXNlKGFjcm9zcyh3aGVyZShpc19kb3VibGUpLCBjdikpCiMgbWFrZSBhIHRpZHksIGxvbmcgZGF0YXNldCAKCmRhdGFfbG9uZyA8LSBkYXRhICU+JSAKICBkcGx5cjo6c2VsZWN0KHRyZWF0bWVudCwgVmVudXMsIG1TY2FybGV0LCByYXRpbykgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKFZlbnVzLCBtU2NhcmxldCwgcmF0aW8pLCAKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAicGFyYW1ldGVyIiwgCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJ2YWx1ZSIpIAojIG5lZWQgdG8gYWxzbyBmb3JtYXQgQ1ZzIGFwcHJvcHJpYXRlbHkgZm9yIGFubm90YXRpbmcKQ1ZzIDwtIENWcyAlPiUgZHBseXI6OnNlbGVjdCh0cmVhdG1lbnQsIFZlbnVzLCBtU2NhcmxldCwgcmF0aW8pICU+JQogICAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKFZlbnVzLCBtU2NhcmxldCwgcmF0aW8pLCAKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAicGFyYW1ldGVyIiwgCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJ2YWx1ZSIpCgojZGF0YQpDVl9wbG90IDwtIGdncGxvdChkYXRhID0gZGF0YV9sb25nLCAKICAgICAgIG1hcHBpbmcgPSBhZXMoeCA9IHZhbHVlLCAKICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSB0cmVhdG1lbnQpKSArIAogIGdlb21fZGVuc2l0eSgpICsgeGxpbShjKC0xLDQpKSArIAogIGxhYnMoeCA9ICJtZWRpYW4gbm9ybWFsaXplZCBpbnRlbnNpdHkiLCBjb2xvciA9ICJ0cmVhdG1lbnQiKSArIAogIGZhY2V0X2dyaWQocGFyYW1ldGVyfi4pICsgdGhlbWVfdGVzdCgpICsgCiAgZ2VvbV90ZXh0KGRhdGEgPSBzdWJzZXQoQ1ZzLCB0cmVhdG1lbnQgPT0gIkF1eGluIiksIAogICAgICAgICAgICAgYWVzKGxhYmVsID0gcGFzdGUwKCJDViA9ICIsIHZhbHVlKSksCiAgICAgICAgICAgICB4ID0gMC4xLCB5ID0gMC42KSArIAogIGdlb21fdGV4dChkYXRhID0gc3Vic2V0KENWcywgdHJlYXRtZW50ID09ICJDb250cm9sIEV0T0giKSwgCiAgICAgICAgICAgICBhZXMobGFiZWwgPSBwYXN0ZTAoIkNWID0gIiwgdmFsdWUpKSwgCiAgICAgICAgICAgIHggPSAxLjgsIHkgPSAwLjYpICsgCiAgc2NhbGVfY29sb3JfdmlyaWRpc19kKG9wdGlvbiA9ICJEIiwgZW5kID0gLjc1LCBkaXJlY3Rpb24gPSAtMSkKQ1ZfcGxvdAoKYGBgCgojIEF1eGluIHByb2RjdXRpb24gaW4gc3RhdGlvbmFyeSBwaGFzZQoKUmVhZCBpbiBhbm5vdGF0ZWQgZmxvd1NldApgYGB7ciwgZXZhbD1GQUxTRX0KZmxvd1NldCA8LSByZWFkLmZsb3dTZXQocGF0aCA9IHBhc3RlMCgifi9Hb29nbGUgRHJpdmUvU2hhcmVkIGRyaXZlcy9QbGFudFN5bkJpb0xhYi9BdXhpbiBCaW9zZW5zb3IgTWFudXNjcmlwdC9BdXhpbiBCaW9zZW5zb3IgRGF0YS9GbG93U2V0cy8iLCBleHBlcmltZW50X2RhdGUsICJfIiwgZXhwZXJpbWVudF9uYW1lKSwgcGhlbm9EYXRhID0gImFubm90YXRpb24udHh0IikKd3JpdGUuZmxvd1NldChmbG93U2V0LCAiZmxvd1NldHMvYXV4aW4tYmlvc3ludGhlc2lzIikKYGBgCmBgYHtyfQpmbG93U2V0IDwtIHJlYWQuZmxvd1NldChwYXRoID0gImZsb3dTZXRzL2F1eGluLWJpb3N5bnRoZXNpcy8iLCBwaGVub0RhdGEgPSAiYW5ub3RhdGlvbi50eHQiKQpgYGAKCiMjIFN1bW1hcnkgQW5hbHlzaXMKCmBgYHtyfQpsb2FkKCJQU0JfQWNjdXJpX1czMDMuUkRhdGEiKQpkYXRfc3VtIDwtIHN1bW1hcml6ZUZsb3coZmxvd1NldCwgcGxvaWR5ID0gImhhcGxvaWQiLCBvbmx5ID0gInllYXN0IikgIyBUaGVzZSBnYXRlcyBtaWdodCBub3Qgd29yayB3ZWxsIGZvciBZUEg0OTksIGJ1dCB0aGVyZSB3YXMgYSBsb3Qgb2YgZGVicmlzCmBgYAoKYGBge3J9CmRhdF9zdW0gPC0gbXV0YXRlKC5kYXRhID0gZGF0X3N1bSwgYWNyb3NzKHN0YXJ0c193aXRoKCJGTCIpLCBhcy5udW1lcmljKSkgJT4lCiAgbXV0YXRlKHN0cmFpbiA9IHN0cl9yZW1vdmUoc3RyYWluLCAiIHJhdGlvbWV0cmljIHNlbnNvciIpICU+JSAKICAgICAgICAgICBzdHJfcmVwbGFjZShwYXR0ZXJuID0gImluIHRyYW5zIiwgCiAgICAgICAgICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQgPSAic2luZ2xlLWZ1c2lvbiIpICU+JQogICAgICAgICAgIHN0cl9yZXBsYWNlKHBhdHRlcm4gPSAiaW4gY2lzIiwKICAgICAgICAgICAgICAgICAgICAgICByZXBsYWNlbWVudCA9ICJkdWFsLWZ1c2lvbiIpKQpkYXRfc3VtJHByZWRfYXV4aW4gPC0gZGF0X3N1bSRGTDQuQW1lYW4vZGF0X3N1bSRGTDEuQW1lYW4gCmRhdF9zdW0kcHJlZF9hdXhpbl9TRSA8LSB3aXRoKGRhdF9zdW0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcXJ0KChGTDQuQXNkLzEwMC9GTDQuQW1lYW4pXjIgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoRkwxLkFzZC8xMDAvRkwxLkFtZWFuKV4yKSpwcmVkX2F1eGluKQpkYXRfc3VtJHByZWRfYXV4aW5fc2QgPC0gd2l0aChkYXRfc3VtLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3FydCgoRkw0LkFzZC9GTDQuQW1lYW4pXjIgKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKEZMMS5Bc2QvRkwxLkFtZWFuKV4yKSpwcmVkX2F1eGluKQpgYGAKCmBgYHtyfQpnZ3Bsb3QoZGF0YSA9IGRhdF9zdW0sIAogICAgICAgYWVzKHggPSBmY3RfcmVvcmRlcih0cmVhdCwgcHJlZF9hdXhpbiksIHkgPSBwcmVkX2F1eGluLAogICAgICAgICAgIGNvbG9yID0gZmFjdG9yKHN0cmFpbikpKSArCiAgZ2VvbV9wb2ludCgpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGp1c3QgPSAxLCB2anVzdCA9IDEpKSArIAogIGZhY2V0X2dyaWQoLn5zdHJhaW4sIHNjYWxlcyA9ICJmcmVlX3giKSArIGNvb3JkX2ZsaXAoKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsIAogICAgICAgIGxlZ2VuZC5kaXJlY3Rpb24gPSAidmVydGljYWwiKSArIAogIGxhYnMoeCA9ICIiLCB5ID0gIlByZWRpY3RlZCBhdXhpbiAobVNjYXJsZXQtSS9WZW51cy1JQUExNykiLCAKICAgICAgIGNvbG9yID0gInN0cmFpbiIpCmdnc2F2ZSgic3RyYWluX3NlbnNvcl9jb21wYXJpc29uX3Jhdy5wZGYiLCB3aWR0aCA9IDgsIGhlaWdodCA9IDMpCmBgYAoKYGBge3J9CmRhdF9zdW0gPC0gZGF0X3N1bSAlPiUgZ3JvdXBfYnkoc3RyYWluKSAlPiUgCiAgbXV0YXRlKG5vcm1fcHJlZF9hdXhpbiA9IAogICAgICAgICAgIHByZWRfYXV4aW4gLyBtZWFuKHByZWRfYXV4aW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbd2hpY2goLmRhdGEkdHJlYXQgPT0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYWVyb2JpYyBleHBvbmVudGlhbCBwaGFzZSIpXSkpCgpnZ3Bsb3QoZGF0YSA9IGRhdF9zdW0sIGFlcyh4ID0gZmN0X3Jlb3JkZXIodHJlYXQsIG5vcm1fcHJlZF9hdXhpbiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBub3JtX3ByZWRfYXV4aW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gZmFjdG9yKHN0cmFpbikpKSArCiAgZ2VvbV9wb2ludChwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcih3aWR0aCA9IDAuMikpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGp1c3QgPSAxLCB2anVzdCA9IDEpKSArIAogIGNvb3JkX2ZsaXAoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLCAKICAgICAgICAgICAgICAgICAgICAgICBsZWdlbmQuZGlyZWN0aW9uID0gInZlcnRpY2FsIikgKyAKICBsYWJzKHggPSAiIiwgCiAgICAgICB5ID0gIk5vcm1hbGl6ZWQgUHJlZGljdGVkIGF1eGluIChtU2NhcmxldC1JL1ZlbnVzLUlBQTE3KSIsIAogICAgICAgY29sb3IgPSAic3RyYWluIikKZ2dzYXZlKCJzdHJhaW5fc2Vuc29yX2NvbXBhcmlzb25fbm9ybS5wZGYiLCB3aWR0aCA9IDUsIGhlaWdodCA9IDUpCgpgYGAKCkZ1bGwgZGlzdHJpYnV0aW9ucwoKYGBge3J9CmRhdGEgPC0gc3RlYWR5U3RhdGUoZmxvd3NldCA9IGZsb3dTZXQsIHBsb2lkeSA9ICJoYXBsb2lkIiwgb25seSA9ICJ5ZWFzdCIpCgpoaXN0KHggPSBsb2coZGF0YSRGTDEuQSwgMTApKQpoaXN0KHggPSBsb2coZGF0YSRGTDQuQSwgMTApKQoKYGBgCgpgYGB7cn0KZGF0YSRwcmVkX2F1eGluIDwtIGRhdGEkRkw0LkEvZGF0YSRGTDEuQQpkYXRhIDwtIGRhdGEgJT4lIGRwbHlyOjpmaWx0ZXIoRkwxLkEgPiAxICYgRkw0LkEgPiAxKQpkYXRhJHRyZWF0IDwtIGRhdGEkdHJlYXQgJT4lIHN0cl9yZW1vdmUoInBoYXNlIikKYGBgCgoKYGBge3J9CmVuZG9nX2F1eGluIDwtIGdncGxvdCgKICBkYXRhID0gc3Vic2V0KAogICAgZGF0YSwKICAgIHN0cmFpbiA9PSAiVzMwMyByYXRpb21ldHJpYyBzZW5zb3IgQUZCMiBpbiBjaXMiICYKICAgICAgcHJlZF9hdXhpbiA8IDIpLAogIGFlcygKICAgIHggPSBwcmVkX2F1eGluLAogICAgeSA9IGZjdF9yZW9yZGVyKHRyZWF0LCAueCA9IHByZWRfYXV4aW4sIAogICAgICAgICAgICAgICAgICAgIC5mdW4gPSBtZWRpYW4sIC5kZXNjID0gVFJVRSkgJT4lIAogICAgICBmY3RfcmVsZXZlbCgiYWVyb2JpYyBleHBvbmVudGlhbCAiLCBhZnRlciA9IEluZiksCiAgICBmaWxsID0gZmFjdG9yKHN0YXQocXVhbnRpbGUpKQogICkKKSArCiAgc3RhdF9kZW5zaXR5X3JpZGdlcygKICAgIGdlb20gPSAiZGVuc2l0eV9yaWRnZXNfZ3JhZGllbnQiLAogICAgY2FsY19lY2RmID0gVFJVRSwKICAgIHF1YW50aWxlcyA9IDQsCiAgICBjb2xvciA9ICJncmV5IiwKICAgIGFscGhhID0gMC41CiAgKSArCiAgc2NhbGVfZmlsbF92aXJpZGlzX2QobmFtZSA9ICJRdWFydGlsZXMiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gTlVMTCkgKwogICNmYWNldF93cmFwKC5+dHJlYXQpICsKICB4bGltKGMoLTAuMSwgMSkpICsKICBsYWJzKHkgPSBOVUxMLCB4ID0gIlByZWRpY3RlZCByZWxhdGl2ZSBhdXhpbiBwcm9kdWN0aW9uIChBVSkgXG4gKEFGQjItbVNjYXJsZXQtSS9WZW51cy1JQUExNykiKSArIHRoZW1lX3JpZGdlcygpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQpnZ3NhdmUoIjIwMjEwNjI2X2F1eGluX3Byb2R1Y3Rpb25fcXVhcnRpbGVzLnBkZiIsIHdpZHRoID0gNSwgaGVpZ2h0ID0gNCkKZW5kb2dfYXV4aW4KYGBgCgojIyBCaW9zZW5zb3Igc2Vuc2l0aXZpdHkgYXQgc3RhdGlvbmFyeSBwaGFzZQoKYGBge3IsIGV2YWw9RkFMU0V9CnBsYXRlXzA5MjgyMDIyIDwtIHJlYWQucGxhdGVTZXQocGF0aCA9ICJ+L0dvb2dsZSBEcml2ZS9TaGFyZWQgZHJpdmVzL1BsYW50U3luQmlvTGFiL1BhdC9FeHBlcmltZW50cy9Eb2VzLXJlc3BvbnNlIGFzc2F5LzA5MjgyMDIyX3lXTDIxMF9EUkEtc3RhdGlvbmFyeS9EYXRhLyIsIHBhdHRlcm4gPSAiUy1EUkEqIikgCmBgYAoKYGBge3IsIGV2YWw9RkFMU0V9CmFubm90YXRpb25fMDkyODIwMjIgPC0gcmVhZC5jc3YoJ34vR29vZ2xlIERyaXZlL1NoYXJlZCBkcml2ZXMvUGxhbnRTeW5CaW9MYWIvUGF0L0V4cGVyaW1lbnRzL0RvZXMtcmVzcG9uc2UgYXNzYXkvMDkyODIwMjJfeVdMMjEwX0RSQS1zdGF0aW9uYXJ5LzA5MjgyMDIyX3N0YXRpb25hcnlwaGFzZV9hbm5vdGF0aW9uLmNzdicpCgphcGxhdGVfMDkyODIwMjIgPC0gYW5ub3RhdGVGbG93U2V0KHlvdXJGbG93U2V0ID0gcGxhdGVfMDkyODIwMjIsIGFubm90YXRpb25fZGYgPSBhbm5vdGF0aW9uXzA5MjgyMDIyLCBtZXJnZUJ5ID0gJ25hbWUnKQpoZWFkKHJvd25hbWVzKHBEYXRhKGFwbGF0ZV8wOTI4MjAyMikpKQpoZWFkKHBEYXRhKGFwbGF0ZV8wOTI4MjAyMikpCndyaXRlLmZsb3dTZXQoYXBsYXRlXzA5MjgyMDIyLCAiZmxvd1NldHMvQUZCMi1kdWFsLXN0YXRpb25hcnkiKQpgYGAKCmBgYHtyfQphcGxhdGVfMDkyODIwMjIgPC0gcmVhZC5mbG93U2V0KHBhdGggPSAiZmxvd1NldHMvQUZCMi1kdWFsLXN0YXRpb25hcnkvIiwgcGhlbm9EYXRhID0gImFubm90YXRpb24udHh0IikKCmRhdF9zdW1Hcl8wOTI4MjAyMiA8LSBzdW1tYXJpemVGbG93KGFwbGF0ZV8wOTI4MjAyMiwgZ2F0ZWQgPSBUUlVFKQoKbW9kZWwuTEw0XzA5MjgyMDIyPC0gZHJtKFlMMS5BbWVhbi9CTDEuQW1lYW5+ZG9zZSwgZGF0YT1zdWJzZXQoZGF0X3N1bUdyXzA5MjgyMDIyLCBzZXQgPT0gIjQiKSwgZmN0PUxMLjQobmFtZXMgPSBjKCJTbG9wZSIsICJMb3dlciBMaW1pdCIsICJVcHBlciBMaW1pdCIsICJFRDUwIikpKQoKcG0yMTBzdGF0IDwtIGV4cGFuZC5ncmlkKHRyZWF0bWVudD1leHAoc2VxKGxvZygxZS01KSwgbG9nKDFlMiksIGxlbmd0aD0xMDAwKSkpIApwbTIxMHN0YXQgPC0gY2JpbmQocG0yMTBzdGF0LHByZWRpY3QobW9kZWwuTEw0XzA5MjgyMDIyLCBuZXdkYXRhPXBtMjEwc3RhdCwgaW50ZXJ2YWw9ImNvbmZpZGVuY2UiKSkgICNtMmFsbCA9IG1vZGVsIG9mIDIxMCBkYXRhCgpwbG90MjEwX3N0YXQgPC0gZ2dwbG90KHN1YnNldChkYXRfc3VtR3JfMDkyODIwMjIsIHNldCA9PSAiNCIpLCAKICAgICAgICAgICAgICAgICAgICAgICBhZXMoeCA9IGRvc2UsIHkgPSBZTDEuQW1lYW4vQkwxLkFtZWFuKSkgICsKIGdlb21fcmliYm9uKGRhdGEgPSBwbTIxMHN0YXQsIAogICAgICAgICAgICAgYWVzKHggPSB0cmVhdG1lbnQsIHkgPSBQcmVkaWN0aW9uLCAKICAgICAgICAgICAgICAgICB5bWluID0gTG93ZXIsIHltYXg9VXBwZXIpLCBhbHBoYSA9IC4yKSArCiAgZ2VvbV9saW5lKGRhdGEgPSBwbTIxMHN0YXQsIGFlcyh4ID0gdHJlYXRtZW50LCB5ID0gUHJlZGljdGlvbikpICsgCiAgeWxhYigiQUZCMi1tU2NhcmxldC1JL1ZlbnVzLUlBQTE3IikgKyAKICB4bGFiKCJFeG9nZW5vdXMgQXV4aW4gKMK1TSkiKSArIAogIHNjYWxlX3hfbG9nMTAobGFiZWxzID0gCiAgICAgICAgICAgICAgICAgIHNjYWxlczo6bGFiZWxfbnVtYmVyKGRyb3AwdHJhaWxpbmcgPSBUUlVFKSkgKyAKICBzY2FsZV9jb2xvcl92aXJpZGlzX2QoKSArIGdlb21fcG9pbnQoKSArIAogIHRoZW1lX2NsYXNzaWMoYmFzZV9zaXplID0gMTQpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSAKcGxvdDIxMF9zdGF0CmBgYAoKIyMgQ29tYmluZWQgZmlndXJlCgpgYGB7ciwgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9NH0KZW5kb2dfYXV4aW4gKyBwbG90MjEwX3N0YXQgKyBwbG90X2Fubm90YXRpb24odGFnX2xldmVscyA9ICJBIikKZ2dzYXZlKCJhdXhpbi1hY2N1bXVsYXRpb24ucGRmIiwgd2lkdGggPSA4LCBoZWlnaHQgPSA0KQpnZ3NhdmUoImF1eGluLWFjY3VtdWxhdGlvbi5wbmciLCB3aWR0aCA9IDgsIGhlaWdodCA9IDQpCmBgYAoKCiMgTXV0YW50IGxpYnJhcnkgYW5hbHlzaXMKCkhlcmUgd2UgYWltIHRvIHRlc3QgYXV4aW4gaW5kdWNlZCBWZW51cy1JQUExNyBkZWdyYWRhdGlvbiByZWxhdGl2ZSB0byB0aGUgYmljaXN0cm9uaWMgbVNjYXJsZXQtSSBjb250cm9sIHdpdGggQUZCMiBleHByZXNzZWQgZnJvbSB0aGUgcDEgcGxhc21pZCBpbiB0aGUgT3J0aG9SZXAgY29udGludW91cyBtdXRhZ2VuZXNpcyBzeXN0ZW0uIAoKIyMgUHJvY2VkdXJlCgpUZW1wZXJhdHVyZSAzMCBkZWdyZWUgY2VsY2l1cwpTaGFraW5nIGF0IDI1MHJwbSAKRE8tVVJBLUhJUywgc3RhcnRpbmcgdm9sdW1lOiAxMCBtTApPdmVybmlnaHQgY29uY2VudHJhdGlvbjogMzAgZXZlbnRzL3VMCjFQTSBzdGFydGVkIGZyb20gMiBjb2xvbmllcwoKSW5pdGlhbCByZWFkaW5nIH4xMEFNCkF1eGluIGNvbmNlbnRyYXRpb246IDEwMCB1TSAoLjElIERNU08pCkFmdGVyIDR0aCByZWFkaW5nOiBCMDQuZmNzCgojIyNJbXBvcnRpbmcgYW5kIGFubm90YXRpbmcgZGF0YQoKYGBge3J9CmFwbGF0ZTEgPC0gcmVhZC5mbG93U2V0KHBhdGggPSAnZmxvd1NldHMvT3J0aG9SZXAnLCBwaGVub0RhdGEgPSAiYW5ub3RhdGlvbi50eHQiKQpkYXRfc3VtIDwtIHN1bW1hcml6ZUZsb3coYXBsYXRlMSwgZ2F0ZWQgPSBUUlVFKQpgYGAKCmBgYHtyIHRpZHlGbG93fQpkYXRhIDwtIGZsb3dUaW1lOjp0aWR5RmxvdyhhcGxhdGUxLCBnYXRlZCA9IFRSVUUpCmRhdGEgPC0gc3Vic2V0KGRhdGEsIEZMNC5BID4gMSkKcmFuZ2UoZGF0YSRGTDEuQSkKcmFuZ2UoZGF0YSRGTDQuQSkKZGF0YSRyYXRpbyA8LSBkYXRhJEZMMS5BIC8gZGF0YSRGTDQuQQpkYXRhIDwtIHN1YnNldChkYXRhLCBkYXRhJHJhdGlvIDwgMTApCmBgYApNYWtlIGEga2VybmVsIGRlbnNpdHkgcGxvdCBvdmVybGFwcGluZyBtdXRhbnQgcG9wdWxhdGlvbiB3aXRoIHBhcmVudCwgRE1TTyBhbmQgSUFBIHRoYXQgd2UgY2FuIHRoZW4gc3RhY2sgYSBmZXcgdGltZXBvaW50cyB3aXRoIGZhY2V0cy4gRm9yIHRpbWVwb2ludHMgaXQgbG9va3MgbGlrZSB0aGUgMm5kLCA3dGggYW5kIDEydGggd291bGQgYmUgYSBnb29kIGRlbW9uc3RyYXRpb24gb2YgdGhlIHRpbWVjb3Vyc2UuCgpgYGB7cn0Kd2VsbHMgPC0gZGF0X3N1bSAlPiUKICAgICAgICAgICAgICAgICAjIEdldCB3ZWxsL2ZpbGUgbmFtZXMgb2YgdGhlIDJuZCwgN3RoIGFuZCAxMnRoIHJlYWRpbmdzIG9mIHRoZSA0IHN0cmFpbnMuIAogICAgICAgICAgICAgICAgIGRwbHlyOjpzbGljZSgxOjQgKyB1bmxpc3QobGFwcGx5KChjKDIsIDcsIDEyKSAtIDEpKjQsIHJlcCwgNCkpKSAlPiUKICAgICAgICAgICAgICAgICBkcGx5cjo6cHVsbCgibmFtZSIpCmRhdGEgPC0gCiAgZHBseXI6OmZpbHRlcihkYXRhLCBuYW1lICVpbiUgd2VsbHMpCgpkYXRhJGFwcHJveHRpbWUgPC0gc2lnbmlmKGRhdGEkZXRpbWUsIGRpZ2l0cyA9IDEpCnNpZ25pZih1bmlxdWUoZGF0YSRhcHByb3h0aW1lKSwgMSkKZGF0YSRhcHByb3h0aW1lIDwtIGFzLmZhY3RvcihkYXRhJGFwcHJveHRpbWUpICU+JSBmY3RfcmVjb2RlKCIwIGhvdXIiID0gIjMwIiwgIjEgaG91ciIgPSAiMjAwIiwgIjYgaG91ciIgPSAiNjAwIikKZGF0YSRzdHJhaW4gPC0gZmN0X3JlY29kZShkYXRhJHN0cmFpbiwgImhpZ2ggZmlkZWxpdHkiID0gIndpbGQiICwgImVycm9yIHByb25lIiA9ICJtdXRhbnQiKQpkYXRhIDwtIAogIGRhdGEgJT4lIAogIG11dGF0ZShWZW51cyA9IEZMMS5BLCAKICAgICAgICAgbVNjYXJsZXQgPSBGTDQuQSwgCiAgICAgICAgIHJhdGlvID0gVmVudXMvbVNjYXJsZXQpCgpjdiA8LSBmdW5jdGlvbih4KSByZXR1cm4ocm91bmQoc2QoeCkvbWVhbih4KSwyKSkKQ1ZzIDwtIGRhdGEgJT4lIGdyb3VwX2J5KHRyZWF0bWVudCwgc3RyYWluKSAlPiUgZHBseXI6OnN1bW1hcmlzZShhY3Jvc3Mod2hlcmUoaXNfZG91YmxlKSwgY3YpKQpDVnMgPC0gQ1ZzICU+JSBkcGx5cjo6c2VsZWN0KHRyZWF0bWVudCwgVmVudXMsIG1TY2FybGV0LCByYXRpbykgJT4lCiAgICBwaXZvdF9sb25nZXIoY29scyA9IGMoVmVudXMsIG1TY2FybGV0LCByYXRpbyksIAogICAgICAgICAgICAgICBuYW1lc190byA9ICJwYXJhbWV0ZXIiLCAKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gInZhbHVlIikKCmtlcm5lbF9wbG90IDwtIGdncGxvdChkYXRhID0gZGF0YSwgCiAgICAgICBtYXBwaW5nID0gYWVzKHggPSByYXRpbywgCiAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gdHJlYXRtZW50LCBsaW5ldHlwZSA9IHN0cmFpbikpICsgCiAgZ2VvbV9kZW5zaXR5KCkgKyBjb29yZF9jYXJ0ZXNpYW4oeCA9IGMoMC41LDIpKSArIAogIGZhY2V0X2dyaWQoYXBwcm94dGltZX4uKSArIHRoZW1lX3Rlc3QoKSArIAogIHNjYWxlX2NvbG9yX3ZpcmlkaXNfZChvcHRpb24gPSAiRCIsIGVuZCA9IC43NSwgZGlyZWN0aW9uID0gLTEpICsgCiAgbGFicyh4ID0gIlZlbnVzLUlBQTE3L21TY2FybGV0IHJhdGlvIiwgbGluZXR5cGUgPSAicG9seW1lcmFzZSIpCmtlcm5lbF9wbG90Cmdnc2F2ZSgib3J0aG9yZXBfZGVncmFkYXRpb24ucGRmIiwgaGVpZ2h0ID0gNCwgd2lkdGggPSA0KQpnZ3NhdmUoIm9ydGhvcmVwX2RlZ3JhZGF0aW9uLnBuZyIsIGhlaWdodCA9IDQsIHdpZHRoID0gNCkKCmBgYAoKIyMgR2F0aW5nIFN0cmF0ZWd5IAoKYGBge3J9CmRhdGEgPC0gYXBsYXRlMVt3ZWxsc10KYGBgCgpUbyBnYXRlIG91dCB0aGUgaGlnaCBGU0MtQSBkZWJyaXMgd2Ugd2lsbCB1c2Ugb25seSB0aGUgbG93ZXIgOTkuNSUgb2YgdGhlIGRhdGEgCmBgYHtyfQpnIDwtIGdhdGVfcXVhbnRpbGUoZnIgPSBkYXRhW1sxXV0sIGNoYW5uZWwgPSAiRlNDLkEiLCBwcm9icyA9IDAuOTk1KQphdXRvcGxvdChkYXRhW1sxXV0sIHggPSAiRlNDLUEiKSArIGdlb21fZ2F0ZShnKQpTdWJzZXQoZGF0YVtbMV1dLCAhZykKYXV0b3Bsb3QoU3Vic2V0KGRhdGFbWzNdXSwgIWcpLCB4ID0gIkZTQy1BIiwgIlNTQy1BIikKYGBgCgpgYGB7cn0KYXV0b3Bsb3QoZGF0YVtbM11dLCAiRlNDLUEiLCAiU1NDLUEiKSArIGdlb21fZ2F0ZShnKQpgYGAKTm93IHdlIG5lZWQgdG8gZ2F0ZSBvdXQgb25seSBzaW5nbGV0IGNlbGxzCmBgYHtyfQpjaG5sIDwtIGMoIkZTQy1BIiwgIkZTQy1IIikKc2luZ2xldHMgPC0gZ2F0ZV9zaW5nbGV0KHggPSBTdWJzZXQoZGF0YVtbMV1dLCAhZyksIGFyZWEgPSAiRlNDLkEiLGhlaWdodCA9ICJGU0MuSCIsIHByZWRpY3Rpb25fbGV2ZWwgPSAwLjk5OSwgbWF4aXQgPSAyMCkKYXV0b3Bsb3QoZGF0YVtbMV1dLCAiRlNDLUEiLCAiRlNDLUgiKSArIGdlb21fZ2F0ZShzaW5nbGV0cykKYGBgCk5vdyB3ZSBjYW4gYXNzZXNzIHRoaXMgc2luZ2xldHMgZ2F0ZSBvdmVyIGZvciBzZXZlcmFsIGZyYW1lcwpgYGB7cn0KbGVuZ3RoKGRhdGEpCmF1dG9wbG90KGRhdGEsIHggPSAiRlNDLUEiLCB5ID0gIkZTQy1IIikgKyBnZW9tX2dhdGUoc2luZ2xldHMpICsgZmFjZXRfd3JhcCgibmFtZSIsIG5jb2wgPSA0KSAKCmF1dG9wbG90KFN1YnNldChkYXRhLCAhZykgJT4lIFN1YnNldChzaW5nbGV0cyksIHggPSAiRkwxLUEiKSArIGZhY2V0X3dyYXAoIm5hbWUiLCBuY29sID0gNCkgCmBgYApgYGB7cn0KYXV0b3Bsb3QoU3Vic2V0KGRhdGEsICFnIHxzaW5nbGV0cyksIHggPSAiRlNDLUEiLCB5ID0gIlNTQy1BIikgKyBmYWNldF93cmFwKCJuYW1lIiwgbmNvbCA9IDQpCmBgYAoKVGhpcyBsb29rcyB2ZXJ5IGNvbnNpc3RlbnQgYWNyb3NzIHRoZSBjb3Vyc2Ugb2YgdGhpcyBleHBlcmltZW50LiBXZSBjYW4gc3VtbWFyaXplIHRoaXMgZ2F0aW5nIGFjcm9zcyB0aGUgd2hvbGUgZXhwZXJpbWVudCwgYnV0IHdpbGwgbm90IHNob3cgdGhpcyBoZXJlLiAKCmBgYHtyfQojc3VtbWFyeShmaWx0ZXIoZGF0YSwgIWcgJiBzaW5nbGV0cykpCmRhdGEgPC0gU3Vic2V0KGRhdGEsICFnICYgc2luZ2xldHMpCmBgYAoKClBsb3QgRmx1b3Jlc2NlbmNlIHZzLiBUaW1lCgpgYGB7ciwgZmlnLndpZHRoID0gNCwgZmlnLmhlaWdodCA9IDR9CmRhdF9zdW0gPC0gc3VtbWFyaXplRmxvdyhkYXRhLCBnYXRlZCA9IFRSVUUpCgpnZ3Bsb3QoZGF0YSA9IGRhdF9zdW0sIGFlcyh4ID0gdGltZSwgeSA9IEZMMS5BbWVhbi9GTDQuQW1lYW4sIGNvbG9yID0gZmFjdG9yKHN0cmFpbiksIGxpbmV0eXBlID0gZmFjdG9yKHRyZWF0bWVudCkpKSsKZ2VvbV9saW5lKCkgKyB4bGFiKCJUaW1lIHBvc3QgZmlyc3QgcmVhZGluZyAobWluKSIpICsKeWxhYigiUmVwb3J0ZXIgRmx1b3Jlc2NlbmNlLCBGTDEgKEFVKSIpICsgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG5hbWUpKQoKZ2dwbG90KGRhdGEgPSBkYXRfc3VtLCBhZXMoeCA9IHRpbWUsIHkgPSBjb25jLCBjb2xvciA9IGZhY3RvcihzdHJhaW4pLCBsaW5ldHlwZSA9IGZhY3Rvcih0cmVhdG1lbnQpKSkrCmdlb21fbGluZSgpICsgeGxhYigiVGltZSBwb3N0IGZpcnN0IHJlYWRpbmcgKG1pbikiKSArCnlsYWIoIlJlcG9ydGVyIEZsdW9yZXNjZW5jZSwgRkwxIChBVSkiKQpgYGAKRGVmaW5lIGEgZ2F0ZSBjb250YWluaW5nIH45NSUgb2YgdGhlIHVudHJlYXRlZCBjZWxscyBleHByZXNzaW5nIHRoZSB3aWxkdHlwZSBwb2x5bWVyYXNlLiAKCmBgYHtyfQpsb2d0IDwtIGVzdGltYXRlTG9naWNsZShkYXRhW1siRTA1LmZjcyJdXSwgY2hhbm5lbHMgPSBjKCJGTDQuQSIsICJGTDEuQSIpKQpkYXRhIDwtIHRyYW5zZm9ybShkYXRhW2MoIkUwNS5mY3MiLCAiRTA2LmZjcyIsICJFMDcuZmNzIiwgIkUwOC5mY3MiKV0sIGxvZ3QpCnVudHJlYXRlZCA8LSBnYXRlX2Zsb3djbHVzdF8yZChkYXRhW1siRTA1LmZjcyJdXSwgeENoYW5uZWwgPSAiRkw0LkEiLCB5Q2hhbm5lbCA9ICJGTDEuQSIsIEsgPSAxLCBxdWFudGlsZSA9IDAuOTAsIGZpbHRlcklkID0gInVudHJlYXRlZCIpCnRyZWF0ZWQgPC0gZ2F0ZV9mbG93Y2x1c3RfMmQoZGF0YVtbIkUwNi5mY3MiXV0sIHhDaGFubmVsID0gIkZMNC5BIiwgeUNoYW5uZWwgPSAiRkwxLkEiLCBLID0gMSwgcXVhbnRpbGUgPSAwLjkwLCBmaWx0ZXJJZCA9ICJ0cmVhdGVkIikKCgoKZ2djeXRvKGRhdGEsIGFlcyh4ID0gIkZMNC5BIiwgeSA9ICJGTDEuQSIpKSArIAogIGdlb21fcG9pbnQoY29sb3IgPSAiZ3JlZW40IiwgYWxwaGEgPSAwLjEsIHNpemUgPSAwLjUpICsgCiAgZ2d0aGVtZXM6OnRoZW1lX2Jhc2UoKSArIAogIGxhYnMoeCA9ICJtU2NhcmxldC1JIChmcmVlIEZQKSIsIHkgPSAiVmVudXMtSUFBMTciKSArCiAgZmFjZXRfZ3JpZChmY3RfcmV2KHN0cmFpbikgJT4lIAogICAgICAgICAgICAgICBmY3RfcmVjb2RlKCJ3aWxkLXR5cGUiID0gIndpbGQiKX50cmVhdG1lbnQpICsgCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKDEuNCwyLjYpLCB5bGltID0gYygxLjQsMi42KSkgKyAKICBnZW9tX2dhdGUodW50cmVhdGVkLCBjb2xvdXIgPSAibWFnZW50YSIsIGxpbmV0eXBlID0gMikgKyAKICBnZW9tX2dhdGUodHJlYXRlZCwgY29sb3VyID0gIm1hZ2VudGEiKSArCiAgZ2VvbV9zdGF0cyhhZGp1c3QgPSBjKDAuMSwgMC4wNSksIHNpemUgPSA0LjUsIGFscGhhID0gMC41KSAKCgpnZ3NhdmUoInNvcnRpbmctc3RyYXRlZ3kucGRmIiwgaGVpZ2h0ID0gNC41LCB3aWR0aCA9IDYpCmdnc2F2ZSgic29ydGluZy1zdHJhdGVneS5wbmciLCBoZWlnaHQgPSA0LjUsIHdpZHRoID0gNikKYGBgCgoKIyMgTXV0YXRpb24gZnJlcXVlbmN5IGNhbGN1bGF0aW9uCiAKQXMgYW4gb3ZlcmVzdGltYXRlLCB0aGVzZSBjZWxscyB3ZXJlIGN1bHR1cmVkIGZvciB+MTIgZ2VuZXJhdGlvbnMgb3ZlciAyNCBob3Vycy4gU28gdGhpcyByZXN1bHRzIGluIDJeMTJeIGNlbGxzIGZvciBlYWNoIGluaXRpYWwuIAoKQUZCMiBpcyAxNzI1IGJwcywgYW5kIHRoZSBtdXRhdGlvbiByYXRlIG9mIHRoZSBlcnJvciBwcm9uZSBwb2x5bWVyYXNlIGlzIGNhbGN1bGF0ZWQgdG8gYmUgJDEgXHRpbWVzIDEwXnstNX0kIHN1YnN0aXR1dGlvbnMgcGVyIGJhc2UuIFdlIHdpbGwgYXNzdW1lIHRoZXJlIGlzIG9ubHkgMSBjb3B5IG9mIHRoZSBwMSBwbGFzbWlkIHBlciBjZWxsLiBXZSB3aWxsIGFsc28gYXNzdW1lIHdpdGhpbmcgdGhpcyBjb2Rpbmcgc2VxdWVuY2UsIGZvciBldmVyeSAyLjEgc3Vic3RpdHV0aW9ucyAoc3ViKSB0aGVyZSBpcyAxIG5vbnN5bm9ueW1vdXMgc3Vic3RpdHV0aW9uIChuc3ViKSwgcGVyIHRoZSBhdmVyYWdlIGFjcm9zcyB0aGUgY29kb24gdGFibGUsIG5vdCBmYWN0b3JpbmcgaW4gY29kb24gdXNhZ2UgYWNyb3NzIFRJUjEuCgokJAogICAgXGJlZ2lue2FycmF5fXtjfGN8Y30KICAgICAxIFx0aW1lcyAxMF57LTV9IFx0ZXh0eyBzdWJ9ICAmIAogICAgIDE3MjUgXHRleHR7IGJhc2VzfSAqIDIgXHRleHR7IChicCl9ICYgCiAgICAgMSBcdGV4dHsgbnN1Yn0gXFwgXGhsaW5lCiAgICAgIFx0ZXh0e2Jhc2V9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiAKICAgICAgXHRleHR7Y2VsbH0gJiAKICAgICAgMi4xIFx0ZXh0eyBzdWJ9CiAgICBcZW5ke2FycmF5fSA9IGByIDEwXi01ICoyMTAwKjIvMi4xYCBcZnJhY3tcdGV4dHtuc3VifX17XHRleHR7Y2VsbH19IAokJApTbyBvbiB0aGUgbG93IGVuZCwgfmByIChjZWxsX25fcmF0ZSA8LSAxMF4tNSAqMTcyNSoyLzIuMSlgIHBlcmNlbnQgb2YgY2VsbHMgaGF2ZSBhIG5vbnN5bm9ueW1vdXMgc3Vic3RpdHV0aW9uIGluICpUSVIxKi4gQnV0IGJlY2F1c2UgdGhpcyBzdWJzdGl0dXRpb24gcmF0ZSBpcyByZWFsbHkgY29tcG91bmRpbmcgb3ZlciAxMiBnZW5lcmF0aW9ucywgdGhpcyBlc3RpbWF0ZSBpcyBxdWl0ZSBsb3cuIAoKQmFzZWQgb24gdGhpcyBiYXNlbGluZSByYXRlIHBlciBjZWxsIChvciBnZW5lcmF0aW9uLCBjZWxsIGR1cGxpY2F0aW9uKSAkciQsIHdlIGNhbiB0aGVuIGNvbXBvdW5kIHRoaXMgb3ZlciAkdCQgZ2VuZXJhdGlvbnMsIHRvIGZpbmQgdGhlIGNvbXBvdW5kZWQgcmF0ZSAkcl9jJC4KJCQKcl9jID0gKDEgKyByKV50LTEgPSAoMStgciBjZWxsX25fcmF0ZWApXnsxMn0tMSA9IAogIGByICgxK2NlbGxfbl9yYXRlKV4xMiAtIDFgCiQkCkFuZCBvbiB0aGUgaGlnaCBlbmQsIHdoaWNoIGlzIGEgbW9yZSBhY2N1cmF0ZSBtZWFzdXJlLCB+YHIgcm91bmQoMTAwKigoMStjZWxsX25fcmF0ZSleMTIgLSAxKSwgMClgJSBvZiBvdXIgcG9wdWxhdGlvbiBjb250YWlucyBhIG5vbnN5bm9ueW1vdXMgc3Vic3RpdHV0aW9uIGluICpUSVIxKi4gCgojIFNlc3Npb24gSW5mbyAKYGBge3J9CnNlc3Npb25JbmZvKCkKYGBgCgo=